Index: Lib/unittest/test/test_case.py =================================================================== --- Lib/unittest/test/test_case.py (revision 83058) +++ Lib/unittest/test/test_case.py (working copy) @@ -4,6 +4,7 @@ import sys from copy import deepcopy +from collections import deque from test import support import unittest @@ -460,21 +461,28 @@ self.assertIn('a', 'abc') self.assertIn(2, [1, 2, 3]) self.assertIn('monkey', animals) + self.assertIn(2, deque([1, 2, 3])) + self.assertIn(2, {1, 2, 3}) self.assertNotIn('d', 'abc') self.assertNotIn(0, [1, 2, 3]) self.assertNotIn('otter', animals) + self.assertNotIn(0, deque([1, 2, 3])) + self.assertNotIn(0, {1, 2, 3}) self.assertRaises(self.failureException, self.assertIn, 'x', 'abc') self.assertRaises(self.failureException, self.assertIn, 4, [1, 2, 3]) self.assertRaises(self.failureException, self.assertIn, 'elephant', animals) + self.assertRaises(self.failureException, self.assertIn, "x", 123) self.assertRaises(self.failureException, self.assertNotIn, 'c', 'abc') self.assertRaises(self.failureException, self.assertNotIn, 1, [1, 2, 3]) self.assertRaises(self.failureException, self.assertNotIn, 'cow', animals) + self.assertRaises(self.failureException, self.assertNotIn, "x", 123) + def testAssertDictContainsSubset(self): self.assertDictContainsSubset({}, {}) self.assertDictContainsSubset({}, {'a': 1}) Index: Lib/unittest/case.py =================================================================== --- Lib/unittest/case.py (revision 83058) +++ Lib/unittest/case.py (working copy) @@ -786,9 +786,19 @@ standardMsg = '\n'.join(lines) self.fail(self._formatMessage(msg, standardMsg)) + + def _check_in_support(self, obj, msg): + """Check that obj supports the `in` operator""" + supported = False + for attr in ("__contains__", "__iter__", "__getitem__"): + supported |= hasattr(obj, attr) + if not supported: + self.fail(self._formatMessage(msg, + '%s does not support the `in` operator' % obj)) def assertIn(self, member, container, msg=None): """Just like self.assertTrue(a in b), but with a nicer default message.""" + self._check_in_support(container, msg) if member not in container: standardMsg = '%s not found in %s' % (safe_repr(member), safe_repr(container)) @@ -796,6 +806,7 @@ def assertNotIn(self, member, container, msg=None): """Just like self.assertTrue(a not in b), but with a nicer default message.""" + self._check_in_support(container, msg) if member in container: standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), safe_repr(container))