1"""Unit tests for collections.py.""" 2 3import collections 4import copy 5import doctest 6import inspect 7import keyword 8import operator 9import pickle 10from random import choice, randrange 11import re 12import string 13import sys 14from test import support 15import types 16import unittest 17 18from collections import namedtuple, Counter, OrderedDict, _count_elements 19from collections import UserDict, UserString, UserList 20from collections import ChainMap 21from collections import deque 22from collections.abc import Awaitable, Coroutine 23from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator 24from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible 25from collections.abc import Sized, Container, Callable, Collection 26from collections.abc import Set, MutableSet 27from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView 28from collections.abc import Sequence, MutableSequence 29from collections.abc import ByteString 30 31 32class TestUserObjects(unittest.TestCase): 33 def _superset_test(self, a, b): 34 self.assertGreaterEqual( 35 set(dir(a)), 36 set(dir(b)), 37 '{a} should have all the methods of {b}'.format( 38 a=a.__name__, 39 b=b.__name__, 40 ), 41 ) 42 def test_str_protocol(self): 43 self._superset_test(UserString, str) 44 45 def test_list_protocol(self): 46 self._superset_test(UserList, list) 47 48 def test_dict_protocol(self): 49 self._superset_test(UserDict, dict) 50 51 52################################################################################ 53### ChainMap (helper class for configparser and the string module) 54################################################################################ 55 56class TestChainMap(unittest.TestCase): 57 58 def test_basics(self): 59 c = ChainMap() 60 c['a'] = 1 61 c['b'] = 2 62 d = c.new_child() 63 d['b'] = 20 64 d['c'] = 30 65 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state 66 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem 67 self.assertEqual(len(d), 3) # check len 68 for key in 'abc': # check contains 69 self.assertIn(key, d) 70 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get 71 self.assertEqual(d.get(k, 100), v) 72 73 del d['b'] # unmask a value 74 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state 75 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem 76 self.assertEqual(len(d), 3) # check len 77 for key in 'abc': # check contains 78 self.assertIn(key, d) 79 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get 80 self.assertEqual(d.get(k, 100), v) 81 self.assertIn(repr(d), [ # check repr 82 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})", 83 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})" 84 ]) 85 86 for e in d.copy(), copy.copy(d): # check shallow copies 87 self.assertEqual(d, e) 88 self.assertEqual(d.maps, e.maps) 89 self.assertIsNot(d, e) 90 self.assertIsNot(d.maps[0], e.maps[0]) 91 for m1, m2 in zip(d.maps[1:], e.maps[1:]): 92 self.assertIs(m1, m2) 93 94 # check deep copies 95 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 96 e = pickle.loads(pickle.dumps(d, proto)) 97 self.assertEqual(d, e) 98 self.assertEqual(d.maps, e.maps) 99 self.assertIsNot(d, e) 100 for m1, m2 in zip(d.maps, e.maps): 101 self.assertIsNot(m1, m2, e) 102 for e in [copy.deepcopy(d), 103 eval(repr(d)) 104 ]: 105 self.assertEqual(d, e) 106 self.assertEqual(d.maps, e.maps) 107 self.assertIsNot(d, e) 108 for m1, m2 in zip(d.maps, e.maps): 109 self.assertIsNot(m1, m2, e) 110 111 f = d.new_child() 112 f['b'] = 5 113 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}]) 114 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents 115 self.assertEqual(f['b'], 5) # find first in chain 116 self.assertEqual(f.parents['b'], 2) # look beyond maps[0] 117 118 def test_constructor(self): 119 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict 120 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list 121 122 def test_bool(self): 123 self.assertFalse(ChainMap()) 124 self.assertFalse(ChainMap({}, {})) 125 self.assertTrue(ChainMap({1:2}, {})) 126 self.assertTrue(ChainMap({}, {1:2})) 127 128 def test_missing(self): 129 class DefaultChainMap(ChainMap): 130 def __missing__(self, key): 131 return 999 132 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30)) 133 for k, v in dict(a=1, b=2, c=30, d=999).items(): 134 self.assertEqual(d[k], v) # check __getitem__ w/missing 135 for k, v in dict(a=1, b=2, c=30, d=77).items(): 136 self.assertEqual(d.get(k, 77), v) # check get() w/ missing 137 for k, v in dict(a=True, b=True, c=True, d=False).items(): 138 self.assertEqual(k in d, v) # check __contains__ w/missing 139 self.assertEqual(d.pop('a', 1001), 1, d) 140 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing 141 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing 142 with self.assertRaises(KeyError): 143 d.popitem() 144 145 def test_dict_coercion(self): 146 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30)) 147 self.assertEqual(dict(d), dict(a=1, b=2, c=30)) 148 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30)) 149 150 def test_new_child(self): 151 'Tests for changes for issue #16613.' 152 c = ChainMap() 153 c['a'] = 1 154 c['b'] = 2 155 m = {'b':20, 'c': 30} 156 d = c.new_child(m) 157 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state 158 self.assertIs(m, d.maps[0]) 159 160 # Use a different map than a dict 161 class lowerdict(dict): 162 def __getitem__(self, key): 163 if isinstance(key, str): 164 key = key.lower() 165 return dict.__getitem__(self, key) 166 def __contains__(self, key): 167 if isinstance(key, str): 168 key = key.lower() 169 return dict.__contains__(self, key) 170 171 c = ChainMap() 172 c['a'] = 1 173 c['b'] = 2 174 m = lowerdict(b=20, c=30) 175 d = c.new_child(m) 176 self.assertIs(m, d.maps[0]) 177 for key in 'abc': # check contains 178 self.assertIn(key, d) 179 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get 180 self.assertEqual(d.get(k, 100), v) 181 182 183################################################################################ 184### Named Tuples 185################################################################################ 186 187TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests 188 189class TestNamedTuple(unittest.TestCase): 190 191 def test_factory(self): 192 Point = namedtuple('Point', 'x y') 193 self.assertEqual(Point.__name__, 'Point') 194 self.assertEqual(Point.__slots__, ()) 195 self.assertEqual(Point.__module__, __name__) 196 self.assertEqual(Point.__getitem__, tuple.__getitem__) 197 self.assertEqual(Point._fields, ('x', 'y')) 198 self.assertIn('class Point(tuple)', Point._source) 199 200 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char 201 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword 202 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit 203 204 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char 205 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword 206 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit 207 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore 208 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field 209 210 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names 211 namedtuple('_', 'a b c') # Test leading underscores in a typename 212 213 nt = namedtuple('nt', 'the quick brown fox') # check unicode input 214 self.assertNotIn("u'", repr(nt._fields)) 215 nt = namedtuple('nt', ('the', 'quick')) # check unicode input 216 self.assertNotIn("u'", repr(nt._fields)) 217 218 self.assertRaises(TypeError, Point._make, [11]) # catch too few args 219 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args 220 221 @unittest.skipIf(sys.flags.optimize >= 2, 222 "Docstrings are omitted with -O2 and above") 223 def test_factory_doc_attr(self): 224 Point = namedtuple('Point', 'x y') 225 self.assertEqual(Point.__doc__, 'Point(x, y)') 226 227 @unittest.skipIf(sys.flags.optimize >= 2, 228 "Docstrings are omitted with -O2 and above") 229 def test_doc_writable(self): 230 Point = namedtuple('Point', 'x y') 231 self.assertEqual(Point.x.__doc__, 'Alias for field number 0') 232 Point.x.__doc__ = 'docstring for Point.x' 233 self.assertEqual(Point.x.__doc__, 'docstring for Point.x') 234 235 def test_name_fixer(self): 236 for spec, renamed in [ 237 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char 238 [('abc', 'class'), ('abc', '_1')], # field has keyword 239 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit 240 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore 241 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field 242 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space 243 ]: 244 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) 245 246 def test_module_parameter(self): 247 NT = namedtuple('NT', ['x', 'y'], module=collections) 248 self.assertEqual(NT.__module__, collections) 249 250 def test_instance(self): 251 Point = namedtuple('Point', 'x y') 252 p = Point(11, 22) 253 self.assertEqual(p, Point(x=11, y=22)) 254 self.assertEqual(p, Point(11, y=22)) 255 self.assertEqual(p, Point(y=22, x=11)) 256 self.assertEqual(p, Point(*(11, 22))) 257 self.assertEqual(p, Point(**dict(x=11, y=22))) 258 self.assertRaises(TypeError, Point, 1) # too few args 259 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args 260 self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument 261 self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument 262 self.assertEqual(repr(p), 'Point(x=11, y=22)') 263 self.assertNotIn('__weakref__', dir(p)) 264 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod 265 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute 266 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method 267 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method 268 269 try: 270 p._replace(x=1, error=2) 271 except ValueError: 272 pass 273 else: 274 self._fail('Did not detect an incorrect fieldname') 275 276 # verify that field string can have commas 277 Point = namedtuple('Point', 'x, y') 278 p = Point(x=11, y=22) 279 self.assertEqual(repr(p), 'Point(x=11, y=22)') 280 281 # verify that fieldspec can be a non-string sequence 282 Point = namedtuple('Point', ('x', 'y')) 283 p = Point(x=11, y=22) 284 self.assertEqual(repr(p), 'Point(x=11, y=22)') 285 286 def test_tupleness(self): 287 Point = namedtuple('Point', 'x y') 288 p = Point(11, 22) 289 290 self.assertIsInstance(p, tuple) 291 self.assertEqual(p, (11, 22)) # matches a real tuple 292 self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple 293 self.assertEqual(list(p), [11, 22]) # coercable to a list 294 self.assertEqual(max(p), 22) # iterable 295 self.assertEqual(max(*p), 22) # star-able 296 x, y = p 297 self.assertEqual(p, (x, y)) # unpacks like a tuple 298 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple 299 self.assertRaises(IndexError, p.__getitem__, 3) 300 301 self.assertEqual(p.x, x) 302 self.assertEqual(p.y, y) 303 self.assertRaises(AttributeError, eval, 'p.z', locals()) 304 305 def test_odd_sizes(self): 306 Zero = namedtuple('Zero', '') 307 self.assertEqual(Zero(), ()) 308 self.assertEqual(Zero._make([]), ()) 309 self.assertEqual(repr(Zero()), 'Zero()') 310 self.assertEqual(Zero()._asdict(), {}) 311 self.assertEqual(Zero()._fields, ()) 312 313 Dot = namedtuple('Dot', 'd') 314 self.assertEqual(Dot(1), (1,)) 315 self.assertEqual(Dot._make([1]), (1,)) 316 self.assertEqual(Dot(1).d, 1) 317 self.assertEqual(repr(Dot(1)), 'Dot(d=1)') 318 self.assertEqual(Dot(1)._asdict(), {'d':1}) 319 self.assertEqual(Dot(1)._replace(d=999), (999,)) 320 self.assertEqual(Dot(1)._fields, ('d',)) 321 322 # n = 5000 323 n = 254 # SyntaxError: more than 255 arguments: 324 names = list(set(''.join([choice(string.ascii_letters) 325 for j in range(10)]) for i in range(n))) 326 n = len(names) 327 Big = namedtuple('Big', names) 328 b = Big(*range(n)) 329 self.assertEqual(b, tuple(range(n))) 330 self.assertEqual(Big._make(range(n)), tuple(range(n))) 331 for pos, name in enumerate(names): 332 self.assertEqual(getattr(b, name), pos) 333 repr(b) # make sure repr() doesn't blow-up 334 d = b._asdict() 335 d_expected = dict(zip(names, range(n))) 336 self.assertEqual(d, d_expected) 337 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)])) 338 b2_expected = list(range(n)) 339 b2_expected[1] = 999 340 b2_expected[-5] = 42 341 self.assertEqual(b2, tuple(b2_expected)) 342 self.assertEqual(b._fields, tuple(names)) 343 344 def test_pickle(self): 345 p = TestNT(x=10, y=20, z=30) 346 for module in (pickle,): 347 loads = getattr(module, 'loads') 348 dumps = getattr(module, 'dumps') 349 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): 350 q = loads(dumps(p, protocol)) 351 self.assertEqual(p, q) 352 self.assertEqual(p._fields, q._fields) 353 self.assertNotIn(b'OrderedDict', dumps(p, protocol)) 354 355 def test_copy(self): 356 p = TestNT(x=10, y=20, z=30) 357 for copier in copy.copy, copy.deepcopy: 358 q = copier(p) 359 self.assertEqual(p, q) 360 self.assertEqual(p._fields, q._fields) 361 362 def test_name_conflicts(self): 363 # Some names like "self", "cls", "tuple", "itemgetter", and "property" 364 # failed when used as field names. Test to make sure these now work. 365 T = namedtuple('T', 'itemgetter property self cls tuple') 366 t = T(1, 2, 3, 4, 5) 367 self.assertEqual(t, (1,2,3,4,5)) 368 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50) 369 self.assertEqual(newt, (10,20,30,40,50)) 370 371 # Broader test of all interesting names in a template 372 with support.captured_stdout() as template: 373 T = namedtuple('T', 'x', verbose=True) 374 words = set(re.findall('[A-Za-z]+', template.getvalue())) 375 words -= set(keyword.kwlist) 376 T = namedtuple('T', words) 377 # test __new__ 378 values = tuple(range(len(words))) 379 t = T(*values) 380 self.assertEqual(t, values) 381 t = T(**dict(zip(T._fields, values))) 382 self.assertEqual(t, values) 383 # test _make 384 t = T._make(values) 385 self.assertEqual(t, values) 386 # exercise __repr__ 387 repr(t) 388 # test _asdict 389 self.assertEqual(t._asdict(), dict(zip(T._fields, values))) 390 # test _replace 391 t = T._make(values) 392 newvalues = tuple(v*10 for v in values) 393 newt = t._replace(**dict(zip(T._fields, newvalues))) 394 self.assertEqual(newt, newvalues) 395 # test _fields 396 self.assertEqual(T._fields, tuple(words)) 397 # test __getnewargs__ 398 self.assertEqual(t.__getnewargs__(), values) 399 400 def test_repr(self): 401 with support.captured_stdout() as template: 402 A = namedtuple('A', 'x', verbose=True) 403 self.assertEqual(repr(A(1)), 'A(x=1)') 404 # repr should show the name of the subclass 405 class B(A): 406 pass 407 self.assertEqual(repr(B(1)), 'B(x=1)') 408 409 def test_source(self): 410 # verify that _source can be run through exec() 411 tmp = namedtuple('NTColor', 'red green blue') 412 globals().pop('NTColor', None) # remove artifacts from other tests 413 exec(tmp._source, globals()) 414 self.assertIn('NTColor', globals()) 415 c = NTColor(10, 20, 30) 416 self.assertEqual((c.red, c.green, c.blue), (10, 20, 30)) 417 self.assertEqual(NTColor._fields, ('red', 'green', 'blue')) 418 globals().pop('NTColor', None) # clean-up after this test 419 420 def test_keyword_only_arguments(self): 421 # See issue 25628 422 with support.captured_stdout() as template: 423 NT = namedtuple('NT', ['x', 'y'], verbose=True) 424 self.assertIn('class NT', NT._source) 425 with self.assertRaises(TypeError): 426 NT = namedtuple('NT', ['x', 'y'], True) 427 428 NT = namedtuple('NT', ['abc', 'def'], rename=True) 429 self.assertEqual(NT._fields, ('abc', '_1')) 430 with self.assertRaises(TypeError): 431 NT = namedtuple('NT', ['abc', 'def'], False, True) 432 433 def test_namedtuple_subclass_issue_24931(self): 434 class Point(namedtuple('_Point', ['x', 'y'])): 435 pass 436 437 a = Point(3, 4) 438 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)])) 439 440 a.w = 5 441 self.assertEqual(a.__dict__, {'w': 5}) 442 443 444################################################################################ 445### Abstract Base Classes 446################################################################################ 447 448class ABCTestCase(unittest.TestCase): 449 450 def validate_abstract_methods(self, abc, *names): 451 methodstubs = dict.fromkeys(names, lambda s, *args: 0) 452 453 # everything should work will all required methods are present 454 C = type('C', (abc,), methodstubs) 455 C() 456 457 # instantiation should fail if a required method is missing 458 for name in names: 459 stubs = methodstubs.copy() 460 del stubs[name] 461 C = type('C', (abc,), stubs) 462 self.assertRaises(TypeError, C, name) 463 464 def validate_isinstance(self, abc, name): 465 stub = lambda s, *args: 0 466 467 C = type('C', (object,), {'__hash__': None}) 468 setattr(C, name, stub) 469 self.assertIsInstance(C(), abc) 470 self.assertTrue(issubclass(C, abc)) 471 472 C = type('C', (object,), {'__hash__': None}) 473 self.assertNotIsInstance(C(), abc) 474 self.assertFalse(issubclass(C, abc)) 475 476 def validate_comparison(self, instance): 477 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] 478 operators = {} 479 for op in ops: 480 name = '__' + op + '__' 481 operators[name] = getattr(operator, name) 482 483 class Other: 484 def __init__(self): 485 self.right_side = False 486 def __eq__(self, other): 487 self.right_side = True 488 return True 489 __lt__ = __eq__ 490 __gt__ = __eq__ 491 __le__ = __eq__ 492 __ge__ = __eq__ 493 __ne__ = __eq__ 494 __ror__ = __eq__ 495 __rand__ = __eq__ 496 __rxor__ = __eq__ 497 __rsub__ = __eq__ 498 499 for name, op in operators.items(): 500 if not hasattr(instance, name): 501 continue 502 other = Other() 503 op(instance, other) 504 self.assertTrue(other.right_side,'Right side not called for %s.%s' 505 % (type(instance), name)) 506 507def _test_gen(): 508 yield 509 510class TestOneTrickPonyABCs(ABCTestCase): 511 512 def test_Awaitable(self): 513 def gen(): 514 yield 515 516 @types.coroutine 517 def coro(): 518 yield 519 520 async def new_coro(): 521 pass 522 523 class Bar: 524 def __await__(self): 525 yield 526 527 class MinimalCoro(Coroutine): 528 def send(self, value): 529 return value 530 def throw(self, typ, val=None, tb=None): 531 super().throw(typ, val, tb) 532 def __await__(self): 533 yield 534 535 non_samples = [None, int(), gen(), object()] 536 for x in non_samples: 537 self.assertNotIsInstance(x, Awaitable) 538 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) 539 540 samples = [Bar(), MinimalCoro()] 541 for x in samples: 542 self.assertIsInstance(x, Awaitable) 543 self.assertTrue(issubclass(type(x), Awaitable)) 544 545 c = coro() 546 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE 547 # flag don't have '__await__' method, hence can't be instances 548 # of Awaitable. Use inspect.isawaitable to detect them. 549 self.assertNotIsInstance(c, Awaitable) 550 551 c = new_coro() 552 self.assertIsInstance(c, Awaitable) 553 c.close() # awoid RuntimeWarning that coro() was not awaited 554 555 class CoroLike: pass 556 Coroutine.register(CoroLike) 557 self.assertTrue(isinstance(CoroLike(), Awaitable)) 558 self.assertTrue(issubclass(CoroLike, Awaitable)) 559 CoroLike = None 560 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache 561 562 def test_Coroutine(self): 563 def gen(): 564 yield 565 566 @types.coroutine 567 def coro(): 568 yield 569 570 async def new_coro(): 571 pass 572 573 class Bar: 574 def __await__(self): 575 yield 576 577 class MinimalCoro(Coroutine): 578 def send(self, value): 579 return value 580 def throw(self, typ, val=None, tb=None): 581 super().throw(typ, val, tb) 582 def __await__(self): 583 yield 584 585 non_samples = [None, int(), gen(), object(), Bar()] 586 for x in non_samples: 587 self.assertNotIsInstance(x, Coroutine) 588 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) 589 590 samples = [MinimalCoro()] 591 for x in samples: 592 self.assertIsInstance(x, Awaitable) 593 self.assertTrue(issubclass(type(x), Awaitable)) 594 595 c = coro() 596 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE 597 # flag don't have '__await__' method, hence can't be instances 598 # of Coroutine. Use inspect.isawaitable to detect them. 599 self.assertNotIsInstance(c, Coroutine) 600 601 c = new_coro() 602 self.assertIsInstance(c, Coroutine) 603 c.close() # awoid RuntimeWarning that coro() was not awaited 604 605 class CoroLike: 606 def send(self, value): 607 pass 608 def throw(self, typ, val=None, tb=None): 609 pass 610 def close(self): 611 pass 612 def __await__(self): 613 pass 614 self.assertTrue(isinstance(CoroLike(), Coroutine)) 615 self.assertTrue(issubclass(CoroLike, Coroutine)) 616 617 class CoroLike: 618 def send(self, value): 619 pass 620 def close(self): 621 pass 622 def __await__(self): 623 pass 624 self.assertFalse(isinstance(CoroLike(), Coroutine)) 625 self.assertFalse(issubclass(CoroLike, Coroutine)) 626 627 def test_Hashable(self): 628 # Check some non-hashables 629 non_samples = [bytearray(), list(), set(), dict()] 630 for x in non_samples: 631 self.assertNotIsInstance(x, Hashable) 632 self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) 633 # Check some hashables 634 samples = [None, 635 int(), float(), complex(), 636 str(), 637 tuple(), frozenset(), 638 int, list, object, type, bytes() 639 ] 640 for x in samples: 641 self.assertIsInstance(x, Hashable) 642 self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) 643 self.assertRaises(TypeError, Hashable) 644 # Check direct subclassing 645 class H(Hashable): 646 def __hash__(self): 647 return super().__hash__() 648 self.assertEqual(hash(H()), 0) 649 self.assertFalse(issubclass(int, H)) 650 self.validate_abstract_methods(Hashable, '__hash__') 651 self.validate_isinstance(Hashable, '__hash__') 652 653 def test_AsyncIterable(self): 654 class AI: 655 async def __aiter__(self): 656 return self 657 self.assertTrue(isinstance(AI(), AsyncIterable)) 658 self.assertTrue(issubclass(AI, AsyncIterable)) 659 # Check some non-iterables 660 non_samples = [None, object, []] 661 for x in non_samples: 662 self.assertNotIsInstance(x, AsyncIterable) 663 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) 664 self.validate_abstract_methods(AsyncIterable, '__aiter__') 665 self.validate_isinstance(AsyncIterable, '__aiter__') 666 667 def test_AsyncIterator(self): 668 class AI: 669 async def __aiter__(self): 670 return self 671 async def __anext__(self): 672 raise StopAsyncIteration 673 self.assertTrue(isinstance(AI(), AsyncIterator)) 674 self.assertTrue(issubclass(AI, AsyncIterator)) 675 non_samples = [None, object, []] 676 # Check some non-iterables 677 for x in non_samples: 678 self.assertNotIsInstance(x, AsyncIterator) 679 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) 680 # Similarly to regular iterators (see issue 10565) 681 class AnextOnly: 682 async def __anext__(self): 683 raise StopAsyncIteration 684 self.assertNotIsInstance(AnextOnly(), AsyncIterator) 685 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') 686 687 def test_Iterable(self): 688 # Check some non-iterables 689 non_samples = [None, 42, 3.14, 1j] 690 for x in non_samples: 691 self.assertNotIsInstance(x, Iterable) 692 self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) 693 # Check some iterables 694 samples = [bytes(), str(), 695 tuple(), list(), set(), frozenset(), dict(), 696 dict().keys(), dict().items(), dict().values(), 697 _test_gen(), 698 (x for x in []), 699 ] 700 for x in samples: 701 self.assertIsInstance(x, Iterable) 702 self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) 703 # Check direct subclassing 704 class I(Iterable): 705 def __iter__(self): 706 return super().__iter__() 707 self.assertEqual(list(I()), []) 708 self.assertFalse(issubclass(str, I)) 709 self.validate_abstract_methods(Iterable, '__iter__') 710 self.validate_isinstance(Iterable, '__iter__') 711 # Check None blocking 712 class It: 713 def __iter__(self): return iter([]) 714 class ItBlocked(It): 715 __iter__ = None 716 self.assertTrue(issubclass(It, Iterable)) 717 self.assertTrue(isinstance(It(), Iterable)) 718 self.assertFalse(issubclass(ItBlocked, Iterable)) 719 self.assertFalse(isinstance(ItBlocked(), Iterable)) 720 721 def test_Reversible(self): 722 # Check some non-reversibles 723 non_samples = [None, 42, 3.14, 1j, dict(), set(), frozenset()] 724 for x in non_samples: 725 self.assertNotIsInstance(x, Reversible) 726 self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) 727 # Check some non-reversible iterables 728 non_reversibles = [dict().keys(), dict().items(), dict().values(), 729 Counter(), Counter().keys(), Counter().items(), 730 Counter().values(), _test_gen(), 731 (x for x in []), iter([]), reversed([])] 732 for x in non_reversibles: 733 self.assertNotIsInstance(x, Reversible) 734 self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) 735 # Check some reversible iterables 736 samples = [bytes(), str(), tuple(), list(), OrderedDict(), 737 OrderedDict().keys(), OrderedDict().items(), 738 OrderedDict().values()] 739 for x in samples: 740 self.assertIsInstance(x, Reversible) 741 self.assertTrue(issubclass(type(x), Reversible), repr(type(x))) 742 # Check also Mapping, MutableMapping, and Sequence 743 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence)) 744 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping)) 745 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping)) 746 # Check direct subclassing 747 class R(Reversible): 748 def __iter__(self): 749 return iter(list()) 750 def __reversed__(self): 751 return iter(list()) 752 self.assertEqual(list(reversed(R())), []) 753 self.assertFalse(issubclass(float, R)) 754 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__') 755 # Check reversible non-iterable (which is not Reversible) 756 class RevNoIter: 757 def __reversed__(self): return reversed([]) 758 class RevPlusIter(RevNoIter): 759 def __iter__(self): return iter([]) 760 self.assertFalse(issubclass(RevNoIter, Reversible)) 761 self.assertFalse(isinstance(RevNoIter(), Reversible)) 762 self.assertTrue(issubclass(RevPlusIter, Reversible)) 763 self.assertTrue(isinstance(RevPlusIter(), Reversible)) 764 # Check None blocking 765 class Rev: 766 def __iter__(self): return iter([]) 767 def __reversed__(self): return reversed([]) 768 class RevItBlocked(Rev): 769 __iter__ = None 770 class RevRevBlocked(Rev): 771 __reversed__ = None 772 self.assertTrue(issubclass(Rev, Reversible)) 773 self.assertTrue(isinstance(Rev(), Reversible)) 774 self.assertFalse(issubclass(RevItBlocked, Reversible)) 775 self.assertFalse(isinstance(RevItBlocked(), Reversible)) 776 self.assertFalse(issubclass(RevRevBlocked, Reversible)) 777 self.assertFalse(isinstance(RevRevBlocked(), Reversible)) 778 779 def test_Collection(self): 780 # Check some non-collections 781 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x] 782 for x in non_collections: 783 self.assertNotIsInstance(x, Collection) 784 self.assertFalse(issubclass(type(x), Collection), repr(type(x))) 785 # Check some non-collection iterables 786 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()), 787 (x for x in []), dict().values()] 788 for x in non_col_iterables: 789 self.assertNotIsInstance(x, Collection) 790 self.assertFalse(issubclass(type(x), Collection), repr(type(x))) 791 # Check some collections 792 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(), 793 list(), dict().keys(), dict().items()] 794 for x in samples: 795 self.assertIsInstance(x, Collection) 796 self.assertTrue(issubclass(type(x), Collection), repr(type(x))) 797 # Check also Mapping, MutableMapping, etc. 798 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence)) 799 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping)) 800 self.assertTrue(issubclass(MutableMapping, Collection), 801 repr(MutableMapping)) 802 self.assertTrue(issubclass(Set, Collection), repr(Set)) 803 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet)) 804 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet)) 805 # Check direct subclassing 806 class Col(Collection): 807 def __iter__(self): 808 return iter(list()) 809 def __len__(self): 810 return 0 811 def __contains__(self, item): 812 return False 813 class DerCol(Col): pass 814 self.assertEqual(list(iter(Col())), []) 815 self.assertFalse(issubclass(list, Col)) 816 self.assertFalse(issubclass(set, Col)) 817 self.assertFalse(issubclass(float, Col)) 818 self.assertEqual(list(iter(DerCol())), []) 819 self.assertFalse(issubclass(list, DerCol)) 820 self.assertFalse(issubclass(set, DerCol)) 821 self.assertFalse(issubclass(float, DerCol)) 822 self.validate_abstract_methods(Collection, '__len__', '__iter__', 823 '__contains__') 824 # Check sized container non-iterable (which is not Collection) etc. 825 class ColNoIter: 826 def __len__(self): return 0 827 def __contains__(self, item): return False 828 class ColNoSize: 829 def __iter__(self): return iter([]) 830 def __contains__(self, item): return False 831 class ColNoCont: 832 def __iter__(self): return iter([]) 833 def __len__(self): return 0 834 self.assertFalse(issubclass(ColNoIter, Collection)) 835 self.assertFalse(isinstance(ColNoIter(), Collection)) 836 self.assertFalse(issubclass(ColNoSize, Collection)) 837 self.assertFalse(isinstance(ColNoSize(), Collection)) 838 self.assertFalse(issubclass(ColNoCont, Collection)) 839 self.assertFalse(isinstance(ColNoCont(), Collection)) 840 # Check None blocking 841 class SizeBlock: 842 def __iter__(self): return iter([]) 843 def __contains__(self): return False 844 __len__ = None 845 class IterBlock: 846 def __len__(self): return 0 847 def __contains__(self): return True 848 __iter__ = None 849 self.assertFalse(issubclass(SizeBlock, Collection)) 850 self.assertFalse(isinstance(SizeBlock(), Collection)) 851 self.assertFalse(issubclass(IterBlock, Collection)) 852 self.assertFalse(isinstance(IterBlock(), Collection)) 853 # Check None blocking in subclass 854 class ColImpl: 855 def __iter__(self): 856 return iter(list()) 857 def __len__(self): 858 return 0 859 def __contains__(self, item): 860 return False 861 class NonCol(ColImpl): 862 __contains__ = None 863 self.assertFalse(issubclass(NonCol, Collection)) 864 self.assertFalse(isinstance(NonCol(), Collection)) 865 866 867 def test_Iterator(self): 868 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] 869 for x in non_samples: 870 self.assertNotIsInstance(x, Iterator) 871 self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) 872 samples = [iter(bytes()), iter(str()), 873 iter(tuple()), iter(list()), iter(dict()), 874 iter(set()), iter(frozenset()), 875 iter(dict().keys()), iter(dict().items()), 876 iter(dict().values()), 877 _test_gen(), 878 (x for x in []), 879 ] 880 for x in samples: 881 self.assertIsInstance(x, Iterator) 882 self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) 883 self.validate_abstract_methods(Iterator, '__next__', '__iter__') 884 885 # Issue 10565 886 class NextOnly: 887 def __next__(self): 888 yield 1 889 return 890 self.assertNotIsInstance(NextOnly(), Iterator) 891 892 def test_Generator(self): 893 class NonGen1: 894 def __iter__(self): return self 895 def __next__(self): return None 896 def close(self): pass 897 def throw(self, typ, val=None, tb=None): pass 898 899 class NonGen2: 900 def __iter__(self): return self 901 def __next__(self): return None 902 def close(self): pass 903 def send(self, value): return value 904 905 class NonGen3: 906 def close(self): pass 907 def send(self, value): return value 908 def throw(self, typ, val=None, tb=None): pass 909 910 non_samples = [ 911 None, 42, 3.14, 1j, b"", "", (), [], {}, set(), 912 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] 913 for x in non_samples: 914 self.assertNotIsInstance(x, Generator) 915 self.assertFalse(issubclass(type(x), Generator), repr(type(x))) 916 917 class Gen: 918 def __iter__(self): return self 919 def __next__(self): return None 920 def close(self): pass 921 def send(self, value): return value 922 def throw(self, typ, val=None, tb=None): pass 923 924 class MinimalGen(Generator): 925 def send(self, value): 926 return value 927 def throw(self, typ, val=None, tb=None): 928 super().throw(typ, val, tb) 929 930 def gen(): 931 yield 1 932 933 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()] 934 for x in samples: 935 self.assertIsInstance(x, Iterator) 936 self.assertIsInstance(x, Generator) 937 self.assertTrue(issubclass(type(x), Generator), repr(type(x))) 938 self.validate_abstract_methods(Generator, 'send', 'throw') 939 940 # mixin tests 941 mgen = MinimalGen() 942 self.assertIs(mgen, iter(mgen)) 943 self.assertIs(mgen.send(None), next(mgen)) 944 self.assertEqual(2, mgen.send(2)) 945 self.assertIsNone(mgen.close()) 946 self.assertRaises(ValueError, mgen.throw, ValueError) 947 self.assertRaisesRegex(ValueError, "^huhu$", 948 mgen.throw, ValueError, ValueError("huhu")) 949 self.assertRaises(StopIteration, mgen.throw, StopIteration()) 950 951 class FailOnClose(Generator): 952 def send(self, value): return value 953 def throw(self, *args): raise ValueError 954 955 self.assertRaises(ValueError, FailOnClose().close) 956 957 class IgnoreGeneratorExit(Generator): 958 def send(self, value): return value 959 def throw(self, *args): pass 960 961 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close) 962 963 def test_AsyncGenerator(self): 964 class NonAGen1: 965 def __aiter__(self): return self 966 def __anext__(self): return None 967 def aclose(self): pass 968 def athrow(self, typ, val=None, tb=None): pass 969 970 class NonAGen2: 971 def __aiter__(self): return self 972 def __anext__(self): return None 973 def aclose(self): pass 974 def asend(self, value): return value 975 976 class NonAGen3: 977 def aclose(self): pass 978 def asend(self, value): return value 979 def athrow(self, typ, val=None, tb=None): pass 980 981 non_samples = [ 982 None, 42, 3.14, 1j, b"", "", (), [], {}, set(), 983 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()] 984 for x in non_samples: 985 self.assertNotIsInstance(x, AsyncGenerator) 986 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x))) 987 988 class Gen: 989 def __aiter__(self): return self 990 async def __anext__(self): return None 991 async def aclose(self): pass 992 async def asend(self, value): return value 993 async def athrow(self, typ, val=None, tb=None): pass 994 995 class MinimalAGen(AsyncGenerator): 996 async def asend(self, value): 997 return value 998 async def athrow(self, typ, val=None, tb=None): 999 await super().athrow(typ, val, tb) 1000 1001 async def gen(): 1002 yield 1 1003 1004 samples = [gen(), Gen(), MinimalAGen()] 1005 for x in samples: 1006 self.assertIsInstance(x, AsyncIterator) 1007 self.assertIsInstance(x, AsyncGenerator) 1008 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x))) 1009 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow') 1010 1011 def run_async(coro): 1012 result = None 1013 while True: 1014 try: 1015 coro.send(None) 1016 except StopIteration as ex: 1017 result = ex.args[0] if ex.args else None 1018 break 1019 return result 1020 1021 # mixin tests 1022 mgen = MinimalAGen() 1023 self.assertIs(mgen, mgen.__aiter__()) 1024 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__())) 1025 self.assertEqual(2, run_async(mgen.asend(2))) 1026 self.assertIsNone(run_async(mgen.aclose())) 1027 with self.assertRaises(ValueError): 1028 run_async(mgen.athrow(ValueError)) 1029 1030 class FailOnClose(AsyncGenerator): 1031 async def asend(self, value): return value 1032 async def athrow(self, *args): raise ValueError 1033 1034 with self.assertRaises(ValueError): 1035 run_async(FailOnClose().aclose()) 1036 1037 class IgnoreGeneratorExit(AsyncGenerator): 1038 async def asend(self, value): return value 1039 async def athrow(self, *args): pass 1040 1041 with self.assertRaises(RuntimeError): 1042 run_async(IgnoreGeneratorExit().aclose()) 1043 1044 def test_Sized(self): 1045 non_samples = [None, 42, 3.14, 1j, 1046 _test_gen(), 1047 (x for x in []), 1048 ] 1049 for x in non_samples: 1050 self.assertNotIsInstance(x, Sized) 1051 self.assertFalse(issubclass(type(x), Sized), repr(type(x))) 1052 samples = [bytes(), str(), 1053 tuple(), list(), set(), frozenset(), dict(), 1054 dict().keys(), dict().items(), dict().values(), 1055 ] 1056 for x in samples: 1057 self.assertIsInstance(x, Sized) 1058 self.assertTrue(issubclass(type(x), Sized), repr(type(x))) 1059 self.validate_abstract_methods(Sized, '__len__') 1060 self.validate_isinstance(Sized, '__len__') 1061 1062 def test_Container(self): 1063 non_samples = [None, 42, 3.14, 1j, 1064 _test_gen(), 1065 (x for x in []), 1066 ] 1067 for x in non_samples: 1068 self.assertNotIsInstance(x, Container) 1069 self.assertFalse(issubclass(type(x), Container), repr(type(x))) 1070 samples = [bytes(), str(), 1071 tuple(), list(), set(), frozenset(), dict(), 1072 dict().keys(), dict().items(), 1073 ] 1074 for x in samples: 1075 self.assertIsInstance(x, Container) 1076 self.assertTrue(issubclass(type(x), Container), repr(type(x))) 1077 self.validate_abstract_methods(Container, '__contains__') 1078 self.validate_isinstance(Container, '__contains__') 1079 1080 def test_Callable(self): 1081 non_samples = [None, 42, 3.14, 1j, 1082 "", b"", (), [], {}, set(), 1083 _test_gen(), 1084 (x for x in []), 1085 ] 1086 for x in non_samples: 1087 self.assertNotIsInstance(x, Callable) 1088 self.assertFalse(issubclass(type(x), Callable), repr(type(x))) 1089 samples = [lambda: None, 1090 type, int, object, 1091 len, 1092 list.append, [].append, 1093 ] 1094 for x in samples: 1095 self.assertIsInstance(x, Callable) 1096 self.assertTrue(issubclass(type(x), Callable), repr(type(x))) 1097 self.validate_abstract_methods(Callable, '__call__') 1098 self.validate_isinstance(Callable, '__call__') 1099 1100 def test_direct_subclassing(self): 1101 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: 1102 class C(B): 1103 pass 1104 self.assertTrue(issubclass(C, B)) 1105 self.assertFalse(issubclass(int, C)) 1106 1107 def test_registration(self): 1108 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: 1109 class C: 1110 __hash__ = None # Make sure it isn't hashable by default 1111 self.assertFalse(issubclass(C, B), B.__name__) 1112 B.register(C) 1113 self.assertTrue(issubclass(C, B)) 1114 1115class WithSet(MutableSet): 1116 1117 def __init__(self, it=()): 1118 self.data = set(it) 1119 1120 def __len__(self): 1121 return len(self.data) 1122 1123 def __iter__(self): 1124 return iter(self.data) 1125 1126 def __contains__(self, item): 1127 return item in self.data 1128 1129 def add(self, item): 1130 self.data.add(item) 1131 1132 def discard(self, item): 1133 self.data.discard(item) 1134 1135class TestCollectionABCs(ABCTestCase): 1136 1137 # XXX For now, we only test some virtual inheritance properties. 1138 # We should also test the proper behavior of the collection ABCs 1139 # as real base classes or mix-in classes. 1140 1141 def test_Set(self): 1142 for sample in [set, frozenset]: 1143 self.assertIsInstance(sample(), Set) 1144 self.assertTrue(issubclass(sample, Set)) 1145 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') 1146 class MySet(Set): 1147 def __contains__(self, x): 1148 return False 1149 def __len__(self): 1150 return 0 1151 def __iter__(self): 1152 return iter([]) 1153 self.validate_comparison(MySet()) 1154 1155 def test_hash_Set(self): 1156 class OneTwoThreeSet(Set): 1157 def __init__(self): 1158 self.contents = [1, 2, 3] 1159 def __contains__(self, x): 1160 return x in self.contents 1161 def __len__(self): 1162 return len(self.contents) 1163 def __iter__(self): 1164 return iter(self.contents) 1165 def __hash__(self): 1166 return self._hash() 1167 a, b = OneTwoThreeSet(), OneTwoThreeSet() 1168 self.assertTrue(hash(a) == hash(b)) 1169 1170 def test_isdisjoint_Set(self): 1171 class MySet(Set): 1172 def __init__(self, itr): 1173 self.contents = itr 1174 def __contains__(self, x): 1175 return x in self.contents 1176 def __iter__(self): 1177 return iter(self.contents) 1178 def __len__(self): 1179 return len([x for x in self.contents]) 1180 s1 = MySet((1, 2, 3)) 1181 s2 = MySet((4, 5, 6)) 1182 s3 = MySet((1, 5, 6)) 1183 self.assertTrue(s1.isdisjoint(s2)) 1184 self.assertFalse(s1.isdisjoint(s3)) 1185 1186 def test_equality_Set(self): 1187 class MySet(Set): 1188 def __init__(self, itr): 1189 self.contents = itr 1190 def __contains__(self, x): 1191 return x in self.contents 1192 def __iter__(self): 1193 return iter(self.contents) 1194 def __len__(self): 1195 return len([x for x in self.contents]) 1196 s1 = MySet((1,)) 1197 s2 = MySet((1, 2)) 1198 s3 = MySet((3, 4)) 1199 s4 = MySet((3, 4)) 1200 self.assertTrue(s2 > s1) 1201 self.assertTrue(s1 < s2) 1202 self.assertFalse(s2 <= s1) 1203 self.assertFalse(s2 <= s3) 1204 self.assertFalse(s1 >= s2) 1205 self.assertEqual(s3, s4) 1206 self.assertNotEqual(s2, s3) 1207 1208 def test_arithmetic_Set(self): 1209 class MySet(Set): 1210 def __init__(self, itr): 1211 self.contents = itr 1212 def __contains__(self, x): 1213 return x in self.contents 1214 def __iter__(self): 1215 return iter(self.contents) 1216 def __len__(self): 1217 return len([x for x in self.contents]) 1218 s1 = MySet((1, 2, 3)) 1219 s2 = MySet((3, 4, 5)) 1220 s3 = s1 & s2 1221 self.assertEqual(s3, MySet((3,))) 1222 1223 def test_MutableSet(self): 1224 self.assertIsInstance(set(), MutableSet) 1225 self.assertTrue(issubclass(set, MutableSet)) 1226 self.assertNotIsInstance(frozenset(), MutableSet) 1227 self.assertFalse(issubclass(frozenset, MutableSet)) 1228 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 1229 'add', 'discard') 1230 1231 def test_issue_5647(self): 1232 # MutableSet.__iand__ mutated the set during iteration 1233 s = WithSet('abcd') 1234 s &= WithSet('cdef') # This used to fail 1235 self.assertEqual(set(s), set('cd')) 1236 1237 def test_issue_4920(self): 1238 # MutableSet.pop() method did not work 1239 class MySet(MutableSet): 1240 __slots__=['__s'] 1241 def __init__(self,items=None): 1242 if items is None: 1243 items=[] 1244 self.__s=set(items) 1245 def __contains__(self,v): 1246 return v in self.__s 1247 def __iter__(self): 1248 return iter(self.__s) 1249 def __len__(self): 1250 return len(self.__s) 1251 def add(self,v): 1252 result=v not in self.__s 1253 self.__s.add(v) 1254 return result 1255 def discard(self,v): 1256 result=v in self.__s 1257 self.__s.discard(v) 1258 return result 1259 def __repr__(self): 1260 return "MySet(%s)" % repr(list(self)) 1261 s = MySet([5,43,2,1]) 1262 self.assertEqual(s.pop(), 1) 1263 1264 def test_issue8750(self): 1265 empty = WithSet() 1266 full = WithSet(range(10)) 1267 s = WithSet(full) 1268 s -= s 1269 self.assertEqual(s, empty) 1270 s = WithSet(full) 1271 s ^= s 1272 self.assertEqual(s, empty) 1273 s = WithSet(full) 1274 s &= s 1275 self.assertEqual(s, full) 1276 s |= s 1277 self.assertEqual(s, full) 1278 1279 def test_issue16373(self): 1280 # Recursion error comparing comparable and noncomparable 1281 # Set instances 1282 class MyComparableSet(Set): 1283 def __contains__(self, x): 1284 return False 1285 def __len__(self): 1286 return 0 1287 def __iter__(self): 1288 return iter([]) 1289 class MyNonComparableSet(Set): 1290 def __contains__(self, x): 1291 return False 1292 def __len__(self): 1293 return 0 1294 def __iter__(self): 1295 return iter([]) 1296 def __le__(self, x): 1297 return NotImplemented 1298 def __lt__(self, x): 1299 return NotImplemented 1300 1301 cs = MyComparableSet() 1302 ncs = MyNonComparableSet() 1303 self.assertFalse(ncs < cs) 1304 self.assertTrue(ncs <= cs) 1305 self.assertFalse(ncs > cs) 1306 self.assertTrue(ncs >= cs) 1307 1308 def test_issue26915(self): 1309 # Container membership test should check identity first 1310 class CustomEqualObject: 1311 def __eq__(self, other): 1312 return False 1313 class CustomSequence(list): 1314 def __contains__(self, value): 1315 return Sequence.__contains__(self, value) 1316 1317 nan = float('nan') 1318 obj = CustomEqualObject() 1319 containers = [ 1320 CustomSequence([nan, obj]), 1321 ItemsView({1: nan, 2: obj}), 1322 ValuesView({1: nan, 2: obj}) 1323 ] 1324 for container in containers: 1325 for elem in container: 1326 self.assertIn(elem, container) 1327 1328 def assertSameSet(self, s1, s2): 1329 # coerce both to a real set then check equality 1330 self.assertSetEqual(set(s1), set(s2)) 1331 1332 def test_Set_interoperability_with_real_sets(self): 1333 # Issue: 8743 1334 class ListSet(Set): 1335 def __init__(self, elements=()): 1336 self.data = [] 1337 for elem in elements: 1338 if elem not in self.data: 1339 self.data.append(elem) 1340 def __contains__(self, elem): 1341 return elem in self.data 1342 def __iter__(self): 1343 return iter(self.data) 1344 def __len__(self): 1345 return len(self.data) 1346 def __repr__(self): 1347 return 'Set({!r})'.format(self.data) 1348 1349 r1 = set('abc') 1350 r2 = set('bcd') 1351 r3 = set('abcde') 1352 f1 = ListSet('abc') 1353 f2 = ListSet('bcd') 1354 f3 = ListSet('abcde') 1355 l1 = list('abccba') 1356 l2 = list('bcddcb') 1357 l3 = list('abcdeedcba') 1358 1359 target = r1 & r2 1360 self.assertSameSet(f1 & f2, target) 1361 self.assertSameSet(f1 & r2, target) 1362 self.assertSameSet(r2 & f1, target) 1363 self.assertSameSet(f1 & l2, target) 1364 1365 target = r1 | r2 1366 self.assertSameSet(f1 | f2, target) 1367 self.assertSameSet(f1 | r2, target) 1368 self.assertSameSet(r2 | f1, target) 1369 self.assertSameSet(f1 | l2, target) 1370 1371 fwd_target = r1 - r2 1372 rev_target = r2 - r1 1373 self.assertSameSet(f1 - f2, fwd_target) 1374 self.assertSameSet(f2 - f1, rev_target) 1375 self.assertSameSet(f1 - r2, fwd_target) 1376 self.assertSameSet(f2 - r1, rev_target) 1377 self.assertSameSet(r1 - f2, fwd_target) 1378 self.assertSameSet(r2 - f1, rev_target) 1379 self.assertSameSet(f1 - l2, fwd_target) 1380 self.assertSameSet(f2 - l1, rev_target) 1381 1382 target = r1 ^ r2 1383 self.assertSameSet(f1 ^ f2, target) 1384 self.assertSameSet(f1 ^ r2, target) 1385 self.assertSameSet(r2 ^ f1, target) 1386 self.assertSameSet(f1 ^ l2, target) 1387 1388 # Don't change the following to use assertLess or other 1389 # "more specific" unittest assertions. The current 1390 # assertTrue/assertFalse style makes the pattern of test 1391 # case combinations clear and allows us to know for sure 1392 # the exact operator being invoked. 1393 1394 # proper subset 1395 self.assertTrue(f1 < f3) 1396 self.assertFalse(f1 < f1) 1397 self.assertFalse(f1 < f2) 1398 self.assertTrue(r1 < f3) 1399 self.assertFalse(r1 < f1) 1400 self.assertFalse(r1 < f2) 1401 self.assertTrue(r1 < r3) 1402 self.assertFalse(r1 < r1) 1403 self.assertFalse(r1 < r2) 1404 with self.assertRaises(TypeError): 1405 f1 < l3 1406 with self.assertRaises(TypeError): 1407 f1 < l1 1408 with self.assertRaises(TypeError): 1409 f1 < l2 1410 1411 # any subset 1412 self.assertTrue(f1 <= f3) 1413 self.assertTrue(f1 <= f1) 1414 self.assertFalse(f1 <= f2) 1415 self.assertTrue(r1 <= f3) 1416 self.assertTrue(r1 <= f1) 1417 self.assertFalse(r1 <= f2) 1418 self.assertTrue(r1 <= r3) 1419 self.assertTrue(r1 <= r1) 1420 self.assertFalse(r1 <= r2) 1421 with self.assertRaises(TypeError): 1422 f1 <= l3 1423 with self.assertRaises(TypeError): 1424 f1 <= l1 1425 with self.assertRaises(TypeError): 1426 f1 <= l2 1427 1428 # proper superset 1429 self.assertTrue(f3 > f1) 1430 self.assertFalse(f1 > f1) 1431 self.assertFalse(f2 > f1) 1432 self.assertTrue(r3 > r1) 1433 self.assertFalse(f1 > r1) 1434 self.assertFalse(f2 > r1) 1435 self.assertTrue(r3 > r1) 1436 self.assertFalse(r1 > r1) 1437 self.assertFalse(r2 > r1) 1438 with self.assertRaises(TypeError): 1439 f1 > l3 1440 with self.assertRaises(TypeError): 1441 f1 > l1 1442 with self.assertRaises(TypeError): 1443 f1 > l2 1444 1445 # any superset 1446 self.assertTrue(f3 >= f1) 1447 self.assertTrue(f1 >= f1) 1448 self.assertFalse(f2 >= f1) 1449 self.assertTrue(r3 >= r1) 1450 self.assertTrue(f1 >= r1) 1451 self.assertFalse(f2 >= r1) 1452 self.assertTrue(r3 >= r1) 1453 self.assertTrue(r1 >= r1) 1454 self.assertFalse(r2 >= r1) 1455 with self.assertRaises(TypeError): 1456 f1 >= l3 1457 with self.assertRaises(TypeError): 1458 f1 >=l1 1459 with self.assertRaises(TypeError): 1460 f1 >= l2 1461 1462 # equality 1463 self.assertTrue(f1 == f1) 1464 self.assertTrue(r1 == f1) 1465 self.assertTrue(f1 == r1) 1466 self.assertFalse(f1 == f3) 1467 self.assertFalse(r1 == f3) 1468 self.assertFalse(f1 == r3) 1469 self.assertFalse(f1 == l3) 1470 self.assertFalse(f1 == l1) 1471 self.assertFalse(f1 == l2) 1472 1473 # inequality 1474 self.assertFalse(f1 != f1) 1475 self.assertFalse(r1 != f1) 1476 self.assertFalse(f1 != r1) 1477 self.assertTrue(f1 != f3) 1478 self.assertTrue(r1 != f3) 1479 self.assertTrue(f1 != r3) 1480 self.assertTrue(f1 != l3) 1481 self.assertTrue(f1 != l1) 1482 self.assertTrue(f1 != l2) 1483 1484 def test_Mapping(self): 1485 for sample in [dict]: 1486 self.assertIsInstance(sample(), Mapping) 1487 self.assertTrue(issubclass(sample, Mapping)) 1488 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', 1489 '__getitem__') 1490 class MyMapping(Mapping): 1491 def __len__(self): 1492 return 0 1493 def __getitem__(self, i): 1494 raise IndexError 1495 def __iter__(self): 1496 return iter(()) 1497 self.validate_comparison(MyMapping()) 1498 self.assertRaises(TypeError, reversed, MyMapping()) 1499 1500 def test_MutableMapping(self): 1501 for sample in [dict]: 1502 self.assertIsInstance(sample(), MutableMapping) 1503 self.assertTrue(issubclass(sample, MutableMapping)) 1504 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', 1505 '__getitem__', '__setitem__', '__delitem__') 1506 1507 def test_MutableMapping_subclass(self): 1508 # Test issue 9214 1509 mymap = UserDict() 1510 mymap['red'] = 5 1511 self.assertIsInstance(mymap.keys(), Set) 1512 self.assertIsInstance(mymap.keys(), KeysView) 1513 self.assertIsInstance(mymap.items(), Set) 1514 self.assertIsInstance(mymap.items(), ItemsView) 1515 1516 mymap = UserDict() 1517 mymap['red'] = 5 1518 z = mymap.keys() | {'orange'} 1519 self.assertIsInstance(z, set) 1520 list(z) 1521 mymap['blue'] = 7 # Shouldn't affect 'z' 1522 self.assertEqual(sorted(z), ['orange', 'red']) 1523 1524 mymap = UserDict() 1525 mymap['red'] = 5 1526 z = mymap.items() | {('orange', 3)} 1527 self.assertIsInstance(z, set) 1528 list(z) 1529 mymap['blue'] = 7 # Shouldn't affect 'z' 1530 self.assertEqual(sorted(z), [('orange', 3), ('red', 5)]) 1531 1532 def test_Sequence(self): 1533 for sample in [tuple, list, bytes, str]: 1534 self.assertIsInstance(sample(), Sequence) 1535 self.assertTrue(issubclass(sample, Sequence)) 1536 self.assertIsInstance(range(10), Sequence) 1537 self.assertTrue(issubclass(range, Sequence)) 1538 self.assertIsInstance(memoryview(b""), Sequence) 1539 self.assertTrue(issubclass(memoryview, Sequence)) 1540 self.assertTrue(issubclass(str, Sequence)) 1541 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', 1542 '__getitem__') 1543 1544 def test_Sequence_mixins(self): 1545 class SequenceSubclass(Sequence): 1546 def __init__(self, seq=()): 1547 self.seq = seq 1548 1549 def __getitem__(self, index): 1550 return self.seq[index] 1551 1552 def __len__(self): 1553 return len(self.seq) 1554 1555 # Compare Sequence.index() behavior to (list|str).index() behavior 1556 def assert_index_same(seq1, seq2, index_args): 1557 try: 1558 expected = seq1.index(*index_args) 1559 except ValueError: 1560 with self.assertRaises(ValueError): 1561 seq2.index(*index_args) 1562 else: 1563 actual = seq2.index(*index_args) 1564 self.assertEqual( 1565 actual, expected, '%r.index%s' % (seq1, index_args)) 1566 1567 for ty in list, str: 1568 nativeseq = ty('abracadabra') 1569 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3)) 1570 seqseq = SequenceSubclass(nativeseq) 1571 for letter in set(nativeseq) | {'z'}: 1572 assert_index_same(nativeseq, seqseq, (letter,)) 1573 for start in range(-3, len(nativeseq) + 3): 1574 assert_index_same(nativeseq, seqseq, (letter, start)) 1575 for stop in range(-3, len(nativeseq) + 3): 1576 assert_index_same( 1577 nativeseq, seqseq, (letter, start, stop)) 1578 1579 def test_ByteString(self): 1580 for sample in [bytes, bytearray]: 1581 self.assertIsInstance(sample(), ByteString) 1582 self.assertTrue(issubclass(sample, ByteString)) 1583 for sample in [str, list, tuple]: 1584 self.assertNotIsInstance(sample(), ByteString) 1585 self.assertFalse(issubclass(sample, ByteString)) 1586 self.assertNotIsInstance(memoryview(b""), ByteString) 1587 self.assertFalse(issubclass(memoryview, ByteString)) 1588 1589 def test_MutableSequence(self): 1590 for sample in [tuple, str, bytes]: 1591 self.assertNotIsInstance(sample(), MutableSequence) 1592 self.assertFalse(issubclass(sample, MutableSequence)) 1593 for sample in [list, bytearray, deque]: 1594 self.assertIsInstance(sample(), MutableSequence) 1595 self.assertTrue(issubclass(sample, MutableSequence)) 1596 self.assertFalse(issubclass(str, MutableSequence)) 1597 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', 1598 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') 1599 1600 def test_MutableSequence_mixins(self): 1601 # Test the mixins of MutableSequence by creating a miminal concrete 1602 # class inherited from it. 1603 class MutableSequenceSubclass(MutableSequence): 1604 def __init__(self): 1605 self.lst = [] 1606 1607 def __setitem__(self, index, value): 1608 self.lst[index] = value 1609 1610 def __getitem__(self, index): 1611 return self.lst[index] 1612 1613 def __len__(self): 1614 return len(self.lst) 1615 1616 def __delitem__(self, index): 1617 del self.lst[index] 1618 1619 def insert(self, index, value): 1620 self.lst.insert(index, value) 1621 1622 mss = MutableSequenceSubclass() 1623 mss.append(0) 1624 mss.extend((1, 2, 3, 4)) 1625 self.assertEqual(len(mss), 5) 1626 self.assertEqual(mss[3], 3) 1627 mss.reverse() 1628 self.assertEqual(mss[3], 1) 1629 mss.pop() 1630 self.assertEqual(len(mss), 4) 1631 mss.remove(3) 1632 self.assertEqual(len(mss), 3) 1633 mss += (10, 20, 30) 1634 self.assertEqual(len(mss), 6) 1635 self.assertEqual(mss[-1], 30) 1636 mss.clear() 1637 self.assertEqual(len(mss), 0) 1638 1639################################################################################ 1640### Counter 1641################################################################################ 1642 1643class CounterSubclassWithSetItem(Counter): 1644 # Test a counter subclass that overrides __setitem__ 1645 def __init__(self, *args, **kwds): 1646 self.called = False 1647 Counter.__init__(self, *args, **kwds) 1648 def __setitem__(self, key, value): 1649 self.called = True 1650 Counter.__setitem__(self, key, value) 1651 1652class CounterSubclassWithGet(Counter): 1653 # Test a counter subclass that overrides get() 1654 def __init__(self, *args, **kwds): 1655 self.called = False 1656 Counter.__init__(self, *args, **kwds) 1657 def get(self, key, default): 1658 self.called = True 1659 return Counter.get(self, key, default) 1660 1661class TestCounter(unittest.TestCase): 1662 1663 def test_basics(self): 1664 c = Counter('abcaba') 1665 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) 1666 self.assertEqual(c, Counter(a=3, b=2, c=1)) 1667 self.assertIsInstance(c, dict) 1668 self.assertIsInstance(c, Mapping) 1669 self.assertTrue(issubclass(Counter, dict)) 1670 self.assertTrue(issubclass(Counter, Mapping)) 1671 self.assertEqual(len(c), 3) 1672 self.assertEqual(sum(c.values()), 6) 1673 self.assertEqual(sorted(c.values()), [1, 2, 3]) 1674 self.assertEqual(sorted(c.keys()), ['a', 'b', 'c']) 1675 self.assertEqual(sorted(c), ['a', 'b', 'c']) 1676 self.assertEqual(sorted(c.items()), 1677 [('a', 3), ('b', 2), ('c', 1)]) 1678 self.assertEqual(c['b'], 2) 1679 self.assertEqual(c['z'], 0) 1680 self.assertEqual(c.__contains__('c'), True) 1681 self.assertEqual(c.__contains__('z'), False) 1682 self.assertEqual(c.get('b', 10), 2) 1683 self.assertEqual(c.get('z', 10), 10) 1684 self.assertEqual(c, dict(a=3, b=2, c=1)) 1685 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") 1686 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) 1687 for i in range(5): 1688 self.assertEqual(c.most_common(i), 1689 [('a', 3), ('b', 2), ('c', 1)][:i]) 1690 self.assertEqual(''.join(sorted(c.elements())), 'aaabbc') 1691 c['a'] += 1 # increment an existing value 1692 c['b'] -= 2 # sub existing value to zero 1693 del c['c'] # remove an entry 1694 del c['c'] # make sure that del doesn't raise KeyError 1695 c['d'] -= 2 # sub from a missing value 1696 c['e'] = -5 # directly assign a missing value 1697 c['f'] += 4 # add to a missing value 1698 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) 1699 self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff') 1700 self.assertEqual(c.pop('f'), 4) 1701 self.assertNotIn('f', c) 1702 for i in range(3): 1703 elem, cnt = c.popitem() 1704 self.assertNotIn(elem, c) 1705 c.clear() 1706 self.assertEqual(c, {}) 1707 self.assertEqual(repr(c), 'Counter()') 1708 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') 1709 self.assertRaises(TypeError, hash, c) 1710 c.update(dict(a=5, b=3)) 1711 c.update(c=1) 1712 c.update(Counter('a' * 50 + 'b' * 30)) 1713 c.update() # test case with no args 1714 c.__init__('a' * 500 + 'b' * 300) 1715 c.__init__('cdc') 1716 c.__init__() 1717 self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) 1718 self.assertEqual(c.setdefault('d', 5), 1) 1719 self.assertEqual(c['d'], 1) 1720 self.assertEqual(c.setdefault('e', 5), 5) 1721 self.assertEqual(c['e'], 5) 1722 1723 def test_init(self): 1724 self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) 1725 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) 1726 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) 1727 self.assertRaises(TypeError, Counter, 42) 1728 self.assertRaises(TypeError, Counter, (), ()) 1729 self.assertRaises(TypeError, Counter.__init__) 1730 1731 def test_update(self): 1732 c = Counter() 1733 c.update(self=42) 1734 self.assertEqual(list(c.items()), [('self', 42)]) 1735 c = Counter() 1736 c.update(iterable=42) 1737 self.assertEqual(list(c.items()), [('iterable', 42)]) 1738 c = Counter() 1739 c.update(iterable=None) 1740 self.assertEqual(list(c.items()), [('iterable', None)]) 1741 self.assertRaises(TypeError, Counter().update, 42) 1742 self.assertRaises(TypeError, Counter().update, {}, {}) 1743 self.assertRaises(TypeError, Counter.update) 1744 1745 def test_copying(self): 1746 # Check that counters are copyable, deepcopyable, picklable, and 1747 #have a repr/eval round-trip 1748 words = Counter('which witch had which witches wrist watch'.split()) 1749 def check(dup): 1750 msg = "\ncopy: %s\nwords: %s" % (dup, words) 1751 self.assertIsNot(dup, words, msg) 1752 self.assertEqual(dup, words) 1753 check(words.copy()) 1754 check(copy.copy(words)) 1755 check(copy.deepcopy(words)) 1756 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1757 with self.subTest(proto=proto): 1758 check(pickle.loads(pickle.dumps(words, proto))) 1759 check(eval(repr(words))) 1760 update_test = Counter() 1761 update_test.update(words) 1762 check(update_test) 1763 check(Counter(words)) 1764 1765 def test_copy_subclass(self): 1766 class MyCounter(Counter): 1767 pass 1768 c = MyCounter('slartibartfast') 1769 d = c.copy() 1770 self.assertEqual(d, c) 1771 self.assertEqual(len(d), len(c)) 1772 self.assertEqual(type(d), type(c)) 1773 1774 def test_conversions(self): 1775 # Convert to: set, list, dict 1776 s = 'she sells sea shells by the sea shore' 1777 self.assertEqual(sorted(Counter(s).elements()), sorted(s)) 1778 self.assertEqual(sorted(Counter(s)), sorted(set(s))) 1779 self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) 1780 self.assertEqual(set(Counter(s)), set(s)) 1781 1782 def test_invariant_for_the_in_operator(self): 1783 c = Counter(a=10, b=-2, c=0) 1784 for elem in c: 1785 self.assertTrue(elem in c) 1786 self.assertIn(elem, c) 1787 1788 def test_multiset_operations(self): 1789 # Verify that adding a zero counter will strip zeros and negatives 1790 c = Counter(a=10, b=-2, c=0) + Counter() 1791 self.assertEqual(dict(c), dict(a=10)) 1792 1793 elements = 'abcd' 1794 for i in range(1000): 1795 # test random pairs of multisets 1796 p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 1797 p.update(e=1, f=-1, g=0) 1798 q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 1799 q.update(h=1, i=-1, j=0) 1800 for counterop, numberop in [ 1801 (Counter.__add__, lambda x, y: max(0, x+y)), 1802 (Counter.__sub__, lambda x, y: max(0, x-y)), 1803 (Counter.__or__, lambda x, y: max(0,x,y)), 1804 (Counter.__and__, lambda x, y: max(0, min(x,y))), 1805 ]: 1806 result = counterop(p, q) 1807 for x in elements: 1808 self.assertEqual(numberop(p[x], q[x]), result[x], 1809 (counterop, x, p, q)) 1810 # verify that results exclude non-positive counts 1811 self.assertTrue(x>0 for x in result.values()) 1812 1813 elements = 'abcdef' 1814 for i in range(100): 1815 # verify that random multisets with no repeats are exactly like sets 1816 p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) 1817 q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) 1818 for counterop, setop in [ 1819 (Counter.__sub__, set.__sub__), 1820 (Counter.__or__, set.__or__), 1821 (Counter.__and__, set.__and__), 1822 ]: 1823 counter_result = counterop(p, q) 1824 set_result = setop(set(p.elements()), set(q.elements())) 1825 self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) 1826 1827 def test_inplace_operations(self): 1828 elements = 'abcd' 1829 for i in range(1000): 1830 # test random pairs of multisets 1831 p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 1832 p.update(e=1, f=-1, g=0) 1833 q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 1834 q.update(h=1, i=-1, j=0) 1835 for inplace_op, regular_op in [ 1836 (Counter.__iadd__, Counter.__add__), 1837 (Counter.__isub__, Counter.__sub__), 1838 (Counter.__ior__, Counter.__or__), 1839 (Counter.__iand__, Counter.__and__), 1840 ]: 1841 c = p.copy() 1842 c_id = id(c) 1843 regular_result = regular_op(c, q) 1844 inplace_result = inplace_op(c, q) 1845 self.assertEqual(inplace_result, regular_result) 1846 self.assertEqual(id(inplace_result), c_id) 1847 1848 def test_subtract(self): 1849 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 1850 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) 1851 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) 1852 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 1853 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) 1854 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) 1855 c = Counter('aaabbcd') 1856 c.subtract('aaaabbcce') 1857 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) 1858 1859 c = Counter() 1860 c.subtract(self=42) 1861 self.assertEqual(list(c.items()), [('self', -42)]) 1862 c = Counter() 1863 c.subtract(iterable=42) 1864 self.assertEqual(list(c.items()), [('iterable', -42)]) 1865 self.assertRaises(TypeError, Counter().subtract, 42) 1866 self.assertRaises(TypeError, Counter().subtract, {}, {}) 1867 self.assertRaises(TypeError, Counter.subtract) 1868 1869 def test_unary(self): 1870 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 1871 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) 1872 self.assertEqual(dict(-c), dict(a=5)) 1873 1874 def test_repr_nonsortable(self): 1875 c = Counter(a=2, b=None) 1876 r = repr(c) 1877 self.assertIn("'a': 2", r) 1878 self.assertIn("'b': None", r) 1879 1880 def test_helper_function(self): 1881 # two paths, one for real dicts and one for other mappings 1882 elems = list('abracadabra') 1883 1884 d = dict() 1885 _count_elements(d, elems) 1886 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) 1887 1888 m = OrderedDict() 1889 _count_elements(m, elems) 1890 self.assertEqual(m, 1891 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) 1892 1893 # test fidelity to the pure python version 1894 c = CounterSubclassWithSetItem('abracadabra') 1895 self.assertTrue(c.called) 1896 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) 1897 c = CounterSubclassWithGet('abracadabra') 1898 self.assertTrue(c.called) 1899 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) 1900 1901 1902################################################################################ 1903### Run tests 1904################################################################################ 1905 1906def test_main(verbose=None): 1907 NamedTupleDocs = doctest.DocTestSuite(module=collections) 1908 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, 1909 TestCollectionABCs, TestCounter, TestChainMap, 1910 TestUserObjects, 1911 ] 1912 support.run_unittest(*test_classes) 1913 support.run_doctest(collections, verbose) 1914 1915 1916if __name__ == "__main__": 1917 test_main(verbose=True) 1918