Skip to content

Commit

Permalink
Show equivalent pytest command (#6363)
Browse files Browse the repository at this point in the history
This is just a quick change to help users trouble-shoot problems with pytest. When there is a failure, we print out the command they can run at the shell to duplicate the error.
  • Loading branch information
ericsnowcurrently committed Jul 2, 2019
1 parent c02d504 commit 796169c
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pythonFiles/testing_tools/adapter/pytest/_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@ def discover(pytestargs=None, hidestdio=False,
# No tests were discovered.
pass
elif ec != 0:
print(('equivalent command: {} -m pytest {}'
).format(sys.executable, util.shlex_unsplit(pytestargs)))
if hidestdio:
print(stdio.getvalue(), file=sys.stderr)
sys.stdout.flush()
raise Exception('pytest discovery failed (exit code {})'.format(ec))
if not _plugin._started:
print(('equivalent command: {} -m pytest {}'
).format(sys.executable, util.shlex_unsplit(pytestargs)))
if hidestdio:
print(stdio.getvalue(), file=sys.stderr)
sys.stdout.flush()
Expand Down
31 changes: 31 additions & 0 deletions pythonFiles/testing_tools/adapter/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,34 @@ def group_attr_names(attrnames):
group = 'other'
grouped[group].append(name)
return grouped


def shlex_unsplit(argv):
"""Return the shell-safe string for the given arguments.
This effectively the equivalent of reversing shlex.split().
"""
argv = [_quote_arg(a) for a in argv]
return ' '.join(argv)


try:
from shlex import quote as _quote_arg
except ImportError:
def _quote_arg(arg):
parts = None
for i, c in enumerate(arg):
if c.isspace():
pass
elif c == '"':
pass
elif c == "'":
c = "'\"'\"'"
else:
continue
if parts is None:
parts = list(arg)
parts[i] = c
if parts is not None:
arg = "'" + ''.join(parts) + "'"
return arg
59 changes: 59 additions & 0 deletions pythonFiles/tests/testing_tools/adapter/test_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import shlex
import unittest

from testing_tools.adapter.util import shlex_unsplit


class ShlexUnsplitTests(unittest.TestCase):

def test_no_args(self):
argv = []
joined = shlex_unsplit(argv)

self.assertEqual(joined, '')
self.assertEqual(shlex.split(joined), argv)

def test_one_arg(self):
argv = ['spam']
joined = shlex_unsplit(argv)

self.assertEqual(joined, 'spam')
self.assertEqual(shlex.split(joined), argv)

def test_multiple_args(self):
argv = [
'-x', 'X',
'-xyz',
'spam',
'eggs',
]
joined = shlex_unsplit(argv)

self.assertEqual(joined, '-x X -xyz spam eggs')
self.assertEqual(shlex.split(joined), argv)

def test_whitespace(self):
argv = [
'-x', 'X Y Z',
'spam spam\tspam',
'eggs',
]
joined = shlex_unsplit(argv)

self.assertEqual(joined, "-x 'X Y Z' 'spam spam\tspam' eggs")
self.assertEqual(shlex.split(joined), argv)

def test_quotation_marks(self):
argv = [
'-x', "'<quoted>'",
'spam"spam"spam',
"ham'ham'ham",
'eggs',
]
joined = shlex_unsplit(argv)

self.assertEqual(joined, "-x ''\"'\"'<quoted>'\"'\"'' 'spam\"spam\"spam' 'ham'\"'\"'ham'\"'\"'ham' eggs")
self.assertEqual(shlex.split(joined), argv)

0 comments on commit 796169c

Please sign in to comment.