[Pytest-commit] commit/tox: 3 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Tue Oct 22 11:22:27 CEST 2013
3 new commits in tox:
https://bitbucket.org/hpk42/tox/commits/f8af400bcecc/
Changeset: f8af400bcecc
User: hpk42
Date: 2013-10-22 10:59:09
Summary: 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.
Affected #: 4 files
diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,11 @@
1.6.2.dev
---------
+- 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.
+
- fix issue128: enable full substitution in install_command,
thanks for the PR to Ronald Evers
diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 tox/_cmdline.py
--- a/tox/_cmdline.py
+++ b/tox/_cmdline.py
@@ -93,7 +93,8 @@
if cwd is None:
# XXX cwd = self.session.config.cwd
cwd = py.path.local()
- popen = self._popen(args, cwd, env=env, stdout=f, stderr=STDOUT)
+ popen = self._popen(args, cwd, env=env,
+ stdout=f, stderr=STDOUT)
popen.outpath = outpath
popen.args = [str(x) for x in args]
popen.cwd = cwd
@@ -150,6 +151,7 @@
if env is None:
env = os.environ.copy()
return self.session.popen(args, shell=False, cwd=str(cwd),
+ universal_newlines=True,
stdout=stdout, stderr=stderr, env=env)
diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 tox/_pytestplugin.py
--- a/tox/_pytestplugin.py
+++ b/tox/_pytestplugin.py
@@ -130,6 +130,7 @@
def make_emptydir(self, path):
pass
def popen(self, args, cwd, shell=None,
+ universal_newlines=False,
stdout=None, stderr=None, env=None):
pm = pcallMock(args, cwd, env, stdout, stderr, shell)
self._pcalls.append(pm)
diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 tox/_venv.py
--- a/tox/_venv.py
+++ b/tox/_venv.py
@@ -228,7 +228,7 @@
args = [self.envconfig.envpython, str(setup_py), '--name']
output = action.popen(args, cwd=setupdir, redirect=False,
returnout=True)
- name = output.strip().decode('utf-8')
+ name = output.strip()
egg_info = setupdir.join('.'.join((name, 'egg-info')))
for conf_file in (setup_py, setup_cfg):
if (not egg_info.check() or (conf_file.check()
https://bitbucket.org/hpk42/tox/commits/f15199a9ec78/
Changeset: f15199a9ec78
User: hpk42
Date: 2013-10-22 11:04:11
Summary: more windows parsing fixes
Affected #: 5 files
diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,7 +9,8 @@
- fix issue128: enable full substitution in install_command,
thanks for the PR to Ronald Evers
-- fix windows parsing/escaping
+- rework and simplify "commands" parsing and in particular posargs
+ substitutions to avoid various win32/posix related quoting issues.
1.6.1
-----
diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd setup.py
--- a/setup.py
+++ b/setup.py
@@ -28,7 +28,7 @@
description='virtualenv-based automation of test activities',
long_description=open("README.rst").read(),
url='http://tox.testrun.org/',
- version='1.6.2.dev1',
+ version='1.6.2.dev2',
license='http://opensource.org/licenses/MIT',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
author='holger krekel',
diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd tests/test_config.py
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -1088,14 +1088,14 @@
parsed = list(p.words())
assert parsed == ['nosetests', ' ', '-v', ' ', '-a', ' ', '!deferred', ' ', '--with-doctest', ' ', '[]']
-def test_argv_unquote_single_args():
- argv = ["hello", '"hello2"', "'hello3'"]
- newargv = unquote_single_args(argv)
- assert newargv == ["hello", "hello2", "hello3"]
-def test_argv_roundrobin():
- argv = ["hello", "this\\that"]
- assert string2argv(argv2string(argv)) == argv
- argv = ["hello world"]
- assert string2argv(argv2string(argv)) == argv
+ @pytest.mark.skipif("sys.platform != 'win32'")
+ def test_commands_with_backslash(self, newconfig):
+ config = newconfig([r"hello\world"], """
+ [testenv:py26]
+ commands = some {posargs}
+ """)
+ envconfig = config.envconfigs["py26"]
+ assert envconfig.commands[0] == ["some", r"hello\world"]
+
diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd tox/__init__.py
--- a/tox/__init__.py
+++ b/tox/__init__.py
@@ -1,5 +1,5 @@
#
-__version__ = '1.6.2.dev1'
+__version__ = '1.6.2.dev2'
class exception:
class Error(Exception):
diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd tox/_config.py
--- a/tox/_config.py
+++ b/tox/_config.py
@@ -413,7 +413,7 @@
def addsubstitutions(self, _posargs=None, **kw):
self._subs.update(kw)
if _posargs:
- self._subs['_posargs'] = _posargs
+ self.posargs = _posargs
def getpath(self, section, name, defaultpath):
toxinidir = self._subs['toxinidir']
@@ -468,27 +468,38 @@
return commandlist
def _processcommand(self, command):
- posargs = self._subs.get('_posargs', None)
- words = list(CommandParser(command).words())
- new_command = ''
- for word in words:
- if word == '[]':
+ posargs = getattr(self, "posargs", None)
+
+ # special treat posargs which might contain multiple arguments
+ # in their defaults
+ newcommand = ""
+ for word in CommandParser(command).words():
+ if word.startswith("{posargs:") and word.endswith("}"):
if posargs:
- new_command += ' '.join(posargs)
+ word = "{posargs}"
+ else:
+ word = word[9:-1]
+ newcommand += word
+
+ # now we can properly parse the command
+ argv = []
+ for arg in shlex.split(newcommand):
+ if arg in ('[]', "{posargs}"):
+ if posargs:
+ argv.extend(posargs)
continue
-
- new_word = self._replace(word, quote=True)
- # two passes; we might have substitutions in the result
- new_word = self._replace(new_word, quote=True)
- new_command += new_word
-
- return shlex.split(new_command.strip())
+ new_arg = ""
+ for word in CommandParser(arg).words():
+ new_word = self._replace(word)
+ new_word = self._replace(new_word)
+ new_arg += new_word
+ argv.append(new_arg)
+ return argv
def getargv(self, section, name, default=None, replace=True):
command = self.getdefault(
- section, name, default=default, replace=replace)
-
- return string2argv(command.strip())
+ section, name, default=default, replace=False)
+ return self._processcommand(command.strip())
def getbool(self, section, name, default=None):
s = self.getdefault(section, name, default)
@@ -527,22 +538,7 @@
#print "getdefault", section, name, "returned", repr(x)
return x
- def _replace_posargs(self, match, quote):
- return self._do_replace_posargs(lambda: match.group('substitution_value'))
-
- def _do_replace_posargs(self, value_func):
- posargs = self._subs.get('_posargs', None)
-
- if posargs:
- return argv2string(posargs)
-
- value = value_func()
- if value:
- return value
-
- return ''
-
- def _replace_env(self, match, quote):
+ def _replace_env(self, match):
envkey = match.group('substitution_value')
if not envkey:
raise tox.exception.ConfigError(
@@ -555,7 +551,7 @@
return os.environ[envkey]
- def _substitute_from_other_section(self, key, quote):
+ def _substitute_from_other_section(self, key):
if key.startswith("[") and "]" in key:
i = key.find("]")
section, item = key[1:i], key[i+1:]
@@ -566,37 +562,25 @@
x = str(self._cfg[section][item])
self._subststack.append((section, item))
try:
- return self._replace(x, quote=quote)
+ return self._replace(x)
finally:
self._subststack.pop()
raise tox.exception.ConfigError(
"substitution key %r not found" % key)
- def _replace_substitution(self, match, quote):
+ def _replace_substitution(self, match):
sub_key = match.group('substitution_value')
val = self._subs.get(sub_key, None)
if val is None:
- val = self._substitute_from_other_section(sub_key, quote)
+ val = self._substitute_from_other_section(sub_key)
if py.builtin.callable(val):
val = val()
- if quote:
- return '"%s"' % str(val).replace('"', r'\"')
- else:
- return str(val)
+ return str(val)
- def _is_bare_posargs(self, groupdict):
- return groupdict.get('substitution_value', None) == 'posargs' \
- and not groupdict.get('sub_type')
-
- def _replace_match(self, match, quote):
+ def _replace_match(self, match):
g = match.groupdict()
- # special case: posargs. If there is a 'posargs' substitution value
- # and no type, handle it as empty posargs
- if self._is_bare_posargs(g):
- return self._do_replace_posargs(lambda: '')
-
# special case: opts and packages. Leave {opts} and
# {packages} intact, they are replaced manually in
# _venv.VirtualEnv.run_install_command.
@@ -605,7 +589,6 @@
return '{%s}' % sub_value
handlers = {
- 'posargs' : self._replace_posargs,
'env' : self._replace_env,
None : self._replace_substitution,
}
@@ -619,22 +602,11 @@
except KeyError:
raise tox.exception.ConfigError("No support for the %s substitution type" % sub_type)
- # quoting is done in handlers, as at least posargs handling is special:
- # all of its arguments are inserted as separate parameters
- return handler(match, quote)
+ return handler(match)
- def _replace_match_quote(self, match):
- return self._replace_match(match, quote=True)
- def _replace_match_no_quote(self, match):
- return self._replace_match(match, quote=False)
-
- def _replace(self, x, quote=False):
+ def _replace(self, x):
if '{' in x:
- if quote:
- replace_func = self._replace_match_quote
- else:
- replace_func = self._replace_match_no_quote
- return RE_ITEM_REF.sub(replace_func, x)
+ return RE_ITEM_REF.sub(self._replace_match, x)
return x
def _parse_command(self, command):
@@ -706,18 +678,3 @@
return 'jenkins'
return None
-
-def unquote_single_args(argv):
- newargv = []
- for arg in argv:
- if len(arg) >=2 and arg[0] == arg[-1]:
- if arg[0] in ("'", '"'):
- arg = arg[1:-1]
- newargv.append(arg)
- return newargv
-
-def string2argv(cmd):
- return unquote_single_args(shlex.split(cmd, posix=False))
-
-def argv2string(argv):
- return subprocess.list2cmdline(argv)
https://bitbucket.org/hpk42/tox/commits/ca1c1d8f9586/
Changeset: ca1c1d8f9586
User: hpk42
Date: 2013-10-22 11:04:11
Summary: a command line specified --installpkg trumps any develop option
Affected #: 3 files
diff -r f15199a9ec78e052b9f9513a34e0e5768e8affdd -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,9 @@
- rework and simplify "commands" parsing and in particular posargs
substitutions to avoid various win32/posix related quoting issues.
+- make sure that the --installpkg option trumps any usedevelop settings
+ in tox.ini or
+
1.6.1
-----
diff -r f15199a9ec78e052b9f9513a34e0e5768e8affdd -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 tests/test_config.py
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -308,7 +308,8 @@
assert argvlist[0] == ["cmd1"]
assert argvlist[1] == ["cmd2", "value2", "other"]
- def test_positional_arguments_are_only_replaced_when_standing_alone(self, tmpdir, newconfig):
+ def test_positional_arguments_are_only_replaced_when_standing_alone(self,
+ tmpdir, newconfig):
config = newconfig("""
[section]
key=
@@ -406,6 +407,13 @@
assert envconfig.envlogdir == envconfig.envdir.join("log")
assert envconfig.setenv is None
+ def test_installpkg_tops_develop(self, newconfig):
+ config = newconfig(["--installpkg=abc"], """
+ [testenv]
+ usedevelop = True
+ """)
+ assert not config.envconfigs["python"].develop
+
def test_specific_command_overrides(self, tmpdir, newconfig):
config = newconfig("""
[testenv]
diff -r f15199a9ec78e052b9f9513a34e0e5768e8affdd -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 tox/_config.py
--- a/tox/_config.py
+++ b/tox/_config.py
@@ -272,7 +272,8 @@
vc.config = config
reader = IniReader(self._cfg, fallbacksections=["testenv"])
reader.addsubstitutions(**subs)
- vc.develop = reader.getbool(section, "usedevelop", config.option.develop)
+ vc.develop = not config.option.installpkg and \
+ reader.getbool(section, "usedevelop", config.option.develop)
vc.envdir = reader.getpath(section, "envdir", "{toxworkdir}/%s" % name)
vc.args_are_paths = reader.getbool(section, "args_are_paths", True)
if reader.getdefault(section, "python", None):
Repository URL: https://bitbucket.org/hpk42/tox/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the pytest-commit
mailing list