Skip to content

Commit 48fbe52

Browse files
bpo-30664: The description of a unittest subtest now preserves the (#2265)
order of keyword arguments of TestCase.subTest().
1 parent c38e32a commit 48fbe52

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

Lib/unittest/case.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,16 @@ def __exit__(self, exc_type, exc_value, tb):
338338
.format(logging.getLevelName(self.level), self.logger.name))
339339

340340

341+
class _OrderedChainMap(collections.ChainMap):
342+
def __iter__(self):
343+
seen = set()
344+
for mapping in self.maps:
345+
for k in mapping:
346+
if k not in seen:
347+
seen.add(k)
348+
yield k
349+
350+
341351
class TestCase(object):
342352
"""A class whose instances are single test cases.
343353
@@ -514,7 +524,7 @@ def subTest(self, msg=_subtest_msg_sentinel, **params):
514524
return
515525
parent = self._subtest
516526
if parent is None:
517-
params_map = collections.ChainMap(params)
527+
params_map = _OrderedChainMap(params)
518528
else:
519529
params_map = parent.params.new_child(params)
520530
self._subtest = _SubTest(self, msg, params_map)
@@ -1418,7 +1428,7 @@ def _subDescription(self):
14181428
if self.params:
14191429
params_desc = ', '.join(
14201430
"{}={!r}".format(k, v)
1421-
for (k, v) in sorted(self.params.items()))
1431+
for (k, v) in self.params.items())
14221432
parts.append("({})".format(params_desc))
14231433
return " ".join(parts) or '(<subtest>)'
14241434

Lib/unittest/test/test_result.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def testGetSubTestDescriptionWithoutDocstring(self):
307307
self.assertEqual(
308308
result.getDescription(self._subtest),
309309
'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
310-
'.Test_TestResult) (bar=2, foo=1)')
310+
'.Test_TestResult) (foo=1, bar=2)')
311311
with self.subTest('some message'):
312312
result = unittest.TextTestResult(None, True, 1)
313313
self.assertEqual(
@@ -335,12 +335,21 @@ def testGetSubTestDescriptionForFalsyValues(self):
335335

336336
def testGetNestedSubTestDescriptionWithoutDocstring(self):
337337
with self.subTest(foo=1):
338-
with self.subTest(bar=2):
338+
with self.subTest(baz=2, bar=3):
339339
result = unittest.TextTestResult(None, True, 1)
340340
self.assertEqual(
341341
result.getDescription(self._subtest),
342342
'testGetNestedSubTestDescriptionWithoutDocstring '
343-
'(' + __name__ + '.Test_TestResult) (bar=2, foo=1)')
343+
'(' + __name__ + '.Test_TestResult) (baz=2, bar=3, foo=1)')
344+
345+
def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self):
346+
with self.subTest(foo=1, bar=2):
347+
with self.subTest(baz=3, bar=4):
348+
result = unittest.TextTestResult(None, True, 1)
349+
self.assertEqual(
350+
result.getDescription(self._subtest),
351+
'testGetDuplicatedNestedSubTestDescriptionWithoutDocstring '
352+
'(' + __name__ + '.Test_TestResult) (baz=3, bar=4, foo=1)')
344353

345354
@unittest.skipIf(sys.flags.optimize >= 2,
346355
"Docstrings are omitted with -O2 and above")
@@ -362,7 +371,7 @@ def testGetSubTestDescriptionWithOneLineDocstring(self):
362371
self.assertEqual(
363372
result.getDescription(self._subtest),
364373
('testGetSubTestDescriptionWithOneLineDocstring '
365-
'(' + __name__ + '.Test_TestResult) (bar=2, foo=1)\n'
374+
'(' + __name__ + '.Test_TestResult) (foo=1, bar=2)\n'
366375
'Tests getDescription() for a method with a docstring.'))
367376

368377
@unittest.skipIf(sys.flags.optimize >= 2,
@@ -390,7 +399,7 @@ def testGetSubTestDescriptionWithMultiLineDocstring(self):
390399
self.assertEqual(
391400
result.getDescription(self._subtest),
392401
('testGetSubTestDescriptionWithMultiLineDocstring '
393-
'(' + __name__ + '.Test_TestResult) (bar=2, foo=1)\n'
402+
'(' + __name__ + '.Test_TestResult) (foo=1, bar=2)\n'
394403
'Tests getDescription() for a method with a longer '
395404
'docstring.'))
396405

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ Extension Modules
374374
Library
375375
-------
376376

377+
- bpo-30664: The description of a unittest subtest now preserves the order of
378+
keyword arguments of TestCase.subTest().
379+
377380
- [Security] bpo-30730: Prevent environment variables injection in subprocess on
378381
Windows. Prevent passing other environment variables and command arguments.
379382

0 commit comments

Comments
 (0)