1"""Unit tests for collections.py.""" 2 3import collections 4import copy 5import doctest 6import inspect 7import operator 8import pickle 9from random import choice, randrange 10from itertools import product, chain, combinations 11import string 12import sys 13from test import support 14import types 15import unittest 16 17from collections import namedtuple, Counter, OrderedDict, _count_elements 18from collections import UserDict, UserString, UserList 19from collections import ChainMap 20from collections import deque 21from collections.abc import Awaitable, Coroutine 22from collections.abc import AsyncIterator, AsyncIterable, AsyncGenerator 23from collections.abc import Hashable, Iterable, Iterator, Generator, Reversible 24from collections.abc import Sized, Container, Callable, Collection 25from collections.abc import Set, MutableSet 26from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView 27from collections.abc import Sequence, MutableSequence 28from collections.abc import ByteString 29 30 31class TestUserObjects(unittest.TestCase): 32 def _superset_test(self, a, b): 33 self.assertGreaterEqual( 34 set(dir(a)), 35 set(dir(b)), 36 '{a} should have all the methods of {b}'.format( 37 a=a.__name__, 38 b=b.__name__, 39 ), 40 ) 41 42 def _copy_test(self, obj): 43 # Test internal copy 44 obj_copy = obj.copy() 45 self.assertIsNot(obj.data, obj_copy.data) 46 self.assertEqual(obj.data, obj_copy.data) 47 48 # Test copy.copy 49 obj.test = [1234] # Make sure instance vars are also copied. 50 obj_copy = copy.copy(obj) 51 self.assertIsNot(obj.data, obj_copy.data) 52 self.assertEqual(obj.data, obj_copy.data) 53 self.assertIs(obj.test, obj_copy.test) 54 55 def test_str_protocol(self): 56 self._superset_test(UserString, str) 57 58 def test_list_protocol(self): 59 self._superset_test(UserList, list) 60 61 def test_dict_protocol(self): 62 self._superset_test(UserDict, dict) 63 64 def test_list_copy(self): 65 obj = UserList() 66 obj.append(123) 67 self._copy_test(obj) 68 69 def test_dict_copy(self): 70 obj = UserDict() 71 obj[123] = "abc" 72 self._copy_test(obj) 73 74 75################################################################################ 76### ChainMap (helper class for configparser and the string module) 77################################################################################ 78 79class TestChainMap(unittest.TestCase): 80 81 def test_basics(self): 82 c = ChainMap() 83 c['a'] = 1 84 c['b'] = 2 85 d = c.new_child() 86 d['b'] = 20 87 d['c'] = 30 88 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state 89 self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem 90 self.assertEqual(len(d), 3) # check len 91 for key in 'abc': # check contains 92 self.assertIn(key, d) 93 for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get 94 self.assertEqual(d.get(k, 100), v) 95 96 del d['b'] # unmask a value 97 self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state 98 self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem 99 self.assertEqual(len(d), 3) # check len 100 for key in 'abc': # check contains 101 self.assertIn(key, d) 102 for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get 103 self.assertEqual(d.get(k, 100), v) 104 self.assertIn(repr(d), [ # check repr 105 type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})", 106 type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})" 107 ]) 108 109 for e in d.copy(), copy.copy(d): # check shallow copies 110 self.assertEqual(d, e) 111 self.assertEqual(d.maps, e.maps) 112 self.assertIsNot(d, e) 113 self.assertIsNot(d.maps[0], e.maps[0]) 114 for m1, m2 in zip(d.maps[1:], e.maps[1:]): 115 self.assertIs(m1, m2) 116 117 # check deep copies 118 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 119 e = pickle.loads(pickle.dumps(d, proto)) 120 self.assertEqual(d, e) 121 self.assertEqual(d.maps, e.maps) 122 self.assertIsNot(d, e) 123 for m1, m2 in zip(d.maps, e.maps): 124 self.assertIsNot(m1, m2, e) 125 for e in [copy.deepcopy(d), 126 eval(repr(d)) 127 ]: 128 self.assertEqual(d, e) 129 self.assertEqual(d.maps, e.maps) 130 self.assertIsNot(d, e) 131 for m1, m2 in zip(d.maps, e.maps): 132 self.assertIsNot(m1, m2, e) 133 134 f = d.new_child() 135 f['b'] = 5 136 self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}]) 137 self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents 138 self.assertEqual(f['b'], 5) # find first in chain 139 self.assertEqual(f.parents['b'], 2) # look beyond maps[0] 140 141 def test_ordering(self): 142 # Combined order matches a series of dict updates from last to first. 143 # This test relies on the ordering of the underlying dicts. 144 145 baseline = {'music': 'bach', 'art': 'rembrandt'} 146 adjustments = {'art': 'van gogh', 'opera': 'carmen'} 147 148 cm = ChainMap(adjustments, baseline) 149 150 combined = baseline.copy() 151 combined.update(adjustments) 152 153 self.assertEqual(list(combined.items()), list(cm.items())) 154 155 def test_constructor(self): 156 self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict 157 self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list 158 159 def test_bool(self): 160 self.assertFalse(ChainMap()) 161 self.assertFalse(ChainMap({}, {})) 162 self.assertTrue(ChainMap({1:2}, {})) 163 self.assertTrue(ChainMap({}, {1:2})) 164 165 def test_missing(self): 166 class DefaultChainMap(ChainMap): 167 def __missing__(self, key): 168 return 999 169 d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30)) 170 for k, v in dict(a=1, b=2, c=30, d=999).items(): 171 self.assertEqual(d[k], v) # check __getitem__ w/missing 172 for k, v in dict(a=1, b=2, c=30, d=77).items(): 173 self.assertEqual(d.get(k, 77), v) # check get() w/ missing 174 for k, v in dict(a=True, b=True, c=True, d=False).items(): 175 self.assertEqual(k in d, v) # check __contains__ w/missing 176 self.assertEqual(d.pop('a', 1001), 1, d) 177 self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing 178 self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing 179 with self.assertRaises(KeyError): 180 d.popitem() 181 182 def test_order_preservation(self): 183 d = ChainMap( 184 OrderedDict(j=0, h=88888), 185 OrderedDict(), 186 OrderedDict(i=9999, d=4444, c=3333), 187 OrderedDict(f=666, b=222, g=777, c=333, h=888), 188 OrderedDict(), 189 OrderedDict(e=55, b=22), 190 OrderedDict(a=1, b=2, c=3, d=4, e=5), 191 OrderedDict(), 192 ) 193 self.assertEqual(''.join(d), 'abcdefghij') 194 self.assertEqual(list(d.items()), 195 [('a', 1), ('b', 222), ('c', 3333), ('d', 4444), 196 ('e', 55), ('f', 666), ('g', 777), ('h', 88888), 197 ('i', 9999), ('j', 0)]) 198 199 def test_iter_not_calling_getitem_on_maps(self): 200 class DictWithGetItem(UserDict): 201 def __init__(self, *args, **kwds): 202 self.called = False 203 UserDict.__init__(self, *args, **kwds) 204 def __getitem__(self, item): 205 self.called = True 206 UserDict.__getitem__(self, item) 207 208 d = DictWithGetItem(a=1) 209 c = ChainMap(d) 210 d.called = False 211 212 set(c) # iterate over chain map 213 self.assertFalse(d.called, '__getitem__ was called') 214 215 def test_dict_coercion(self): 216 d = ChainMap(dict(a=1, b=2), dict(b=20, c=30)) 217 self.assertEqual(dict(d), dict(a=1, b=2, c=30)) 218 self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30)) 219 220 def test_new_child(self): 221 'Tests for changes for issue #16613.' 222 c = ChainMap() 223 c['a'] = 1 224 c['b'] = 2 225 m = {'b':20, 'c': 30} 226 d = c.new_child(m) 227 self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state 228 self.assertIs(m, d.maps[0]) 229 230 # Use a different map than a dict 231 class lowerdict(dict): 232 def __getitem__(self, key): 233 if isinstance(key, str): 234 key = key.lower() 235 return dict.__getitem__(self, key) 236 def __contains__(self, key): 237 if isinstance(key, str): 238 key = key.lower() 239 return dict.__contains__(self, key) 240 241 c = ChainMap() 242 c['a'] = 1 243 c['b'] = 2 244 m = lowerdict(b=20, c=30) 245 d = c.new_child(m) 246 self.assertIs(m, d.maps[0]) 247 for key in 'abc': # check contains 248 self.assertIn(key, d) 249 for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get 250 self.assertEqual(d.get(k, 100), v) 251 252 c = ChainMap({'a': 1, 'b': 2}) 253 d = c.new_child(b=20, c=30) 254 self.assertEqual(d.maps, [{'b': 20, 'c': 30}, {'a': 1, 'b': 2}]) 255 256 def test_union_operators(self): 257 cm1 = ChainMap(dict(a=1, b=2), dict(c=3, d=4)) 258 cm2 = ChainMap(dict(a=10, e=5), dict(b=20, d=4)) 259 cm3 = cm1.copy() 260 d = dict(a=10, c=30) 261 pairs = [('c', 3), ('p',0)] 262 263 tmp = cm1 | cm2 # testing between chainmaps 264 self.assertEqual(tmp.maps, [cm1.maps[0] | dict(cm2), *cm1.maps[1:]]) 265 cm1 |= cm2 266 self.assertEqual(tmp, cm1) 267 268 tmp = cm2 | d # testing between chainmap and mapping 269 self.assertEqual(tmp.maps, [cm2.maps[0] | d, *cm2.maps[1:]]) 270 self.assertEqual((d | cm2).maps, [d | dict(cm2)]) 271 cm2 |= d 272 self.assertEqual(tmp, cm2) 273 274 # testing behavior between chainmap and iterable key-value pairs 275 with self.assertRaises(TypeError): 276 cm3 | pairs 277 tmp = cm3.copy() 278 cm3 |= pairs 279 self.assertEqual(cm3.maps, [tmp.maps[0] | dict(pairs), *tmp.maps[1:]]) 280 281 # testing proper return types for ChainMap and it's subclasses 282 class Subclass(ChainMap): 283 pass 284 285 class SubclassRor(ChainMap): 286 def __ror__(self, other): 287 return super().__ror__(other) 288 289 tmp = ChainMap() | ChainMap() 290 self.assertIs(type(tmp), ChainMap) 291 self.assertIs(type(tmp.maps[0]), dict) 292 tmp = ChainMap() | Subclass() 293 self.assertIs(type(tmp), ChainMap) 294 self.assertIs(type(tmp.maps[0]), dict) 295 tmp = Subclass() | ChainMap() 296 self.assertIs(type(tmp), Subclass) 297 self.assertIs(type(tmp.maps[0]), dict) 298 tmp = ChainMap() | SubclassRor() 299 self.assertIs(type(tmp), SubclassRor) 300 self.assertIs(type(tmp.maps[0]), dict) 301 302 303################################################################################ 304### Named Tuples 305################################################################################ 306 307TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests 308 309class TestNamedTuple(unittest.TestCase): 310 311 def test_factory(self): 312 Point = namedtuple('Point', 'x y') 313 self.assertEqual(Point.__name__, 'Point') 314 self.assertEqual(Point.__slots__, ()) 315 self.assertEqual(Point.__module__, __name__) 316 self.assertEqual(Point.__getitem__, tuple.__getitem__) 317 self.assertEqual(Point._fields, ('x', 'y')) 318 319 self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char 320 self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword 321 self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit 322 323 self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char 324 self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword 325 self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit 326 self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore 327 self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field 328 329 namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names 330 namedtuple('_', 'a b c') # Test leading underscores in a typename 331 332 nt = namedtuple('nt', 'the quick brown fox') # check unicode input 333 self.assertNotIn("u'", repr(nt._fields)) 334 nt = namedtuple('nt', ('the', 'quick')) # check unicode input 335 self.assertNotIn("u'", repr(nt._fields)) 336 337 self.assertRaises(TypeError, Point._make, [11]) # catch too few args 338 self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args 339 340 def test_defaults(self): 341 Point = namedtuple('Point', 'x y', defaults=(10, 20)) # 2 defaults 342 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20}) 343 self.assertEqual(Point(1, 2), (1, 2)) 344 self.assertEqual(Point(1), (1, 20)) 345 self.assertEqual(Point(), (10, 20)) 346 347 Point = namedtuple('Point', 'x y', defaults=(20,)) # 1 default 348 self.assertEqual(Point._field_defaults, {'y': 20}) 349 self.assertEqual(Point(1, 2), (1, 2)) 350 self.assertEqual(Point(1), (1, 20)) 351 352 Point = namedtuple('Point', 'x y', defaults=()) # 0 defaults 353 self.assertEqual(Point._field_defaults, {}) 354 self.assertEqual(Point(1, 2), (1, 2)) 355 with self.assertRaises(TypeError): 356 Point(1) 357 358 with self.assertRaises(TypeError): # catch too few args 359 Point() 360 with self.assertRaises(TypeError): # catch too many args 361 Point(1, 2, 3) 362 with self.assertRaises(TypeError): # too many defaults 363 Point = namedtuple('Point', 'x y', defaults=(10, 20, 30)) 364 with self.assertRaises(TypeError): # non-iterable defaults 365 Point = namedtuple('Point', 'x y', defaults=10) 366 with self.assertRaises(TypeError): # another non-iterable default 367 Point = namedtuple('Point', 'x y', defaults=False) 368 369 Point = namedtuple('Point', 'x y', defaults=None) # default is None 370 self.assertEqual(Point._field_defaults, {}) 371 self.assertIsNone(Point.__new__.__defaults__, None) 372 self.assertEqual(Point(10, 20), (10, 20)) 373 with self.assertRaises(TypeError): # catch too few args 374 Point(10) 375 376 Point = namedtuple('Point', 'x y', defaults=[10, 20]) # allow non-tuple iterable 377 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20}) 378 self.assertEqual(Point.__new__.__defaults__, (10, 20)) 379 self.assertEqual(Point(1, 2), (1, 2)) 380 self.assertEqual(Point(1), (1, 20)) 381 self.assertEqual(Point(), (10, 20)) 382 383 Point = namedtuple('Point', 'x y', defaults=iter([10, 20])) # allow plain iterator 384 self.assertEqual(Point._field_defaults, {'x': 10, 'y': 20}) 385 self.assertEqual(Point.__new__.__defaults__, (10, 20)) 386 self.assertEqual(Point(1, 2), (1, 2)) 387 self.assertEqual(Point(1), (1, 20)) 388 self.assertEqual(Point(), (10, 20)) 389 390 def test_readonly(self): 391 Point = namedtuple('Point', 'x y') 392 p = Point(11, 22) 393 with self.assertRaises(AttributeError): 394 p.x = 33 395 with self.assertRaises(AttributeError): 396 del p.x 397 with self.assertRaises(TypeError): 398 p[0] = 33 399 with self.assertRaises(TypeError): 400 del p[0] 401 self.assertEqual(p.x, 11) 402 self.assertEqual(p[0], 11) 403 404 @unittest.skipIf(sys.flags.optimize >= 2, 405 "Docstrings are omitted with -O2 and above") 406 def test_factory_doc_attr(self): 407 Point = namedtuple('Point', 'x y') 408 self.assertEqual(Point.__doc__, 'Point(x, y)') 409 Point.__doc__ = '2D point' 410 self.assertEqual(Point.__doc__, '2D point') 411 412 @unittest.skipIf(sys.flags.optimize >= 2, 413 "Docstrings are omitted with -O2 and above") 414 def test_field_doc(self): 415 Point = namedtuple('Point', 'x y') 416 self.assertEqual(Point.x.__doc__, 'Alias for field number 0') 417 self.assertEqual(Point.y.__doc__, 'Alias for field number 1') 418 Point.x.__doc__ = 'docstring for Point.x' 419 self.assertEqual(Point.x.__doc__, 'docstring for Point.x') 420 # namedtuple can mutate doc of descriptors independently 421 Vector = namedtuple('Vector', 'x y') 422 self.assertEqual(Vector.x.__doc__, 'Alias for field number 0') 423 Vector.x.__doc__ = 'docstring for Vector.x' 424 self.assertEqual(Vector.x.__doc__, 'docstring for Vector.x') 425 426 @support.cpython_only 427 @unittest.skipIf(sys.flags.optimize >= 2, 428 "Docstrings are omitted with -O2 and above") 429 def test_field_doc_reuse(self): 430 P = namedtuple('P', ['m', 'n']) 431 Q = namedtuple('Q', ['o', 'p']) 432 self.assertIs(P.m.__doc__, Q.o.__doc__) 433 self.assertIs(P.n.__doc__, Q.p.__doc__) 434 435 @support.cpython_only 436 def test_field_repr(self): 437 Point = namedtuple('Point', 'x y') 438 self.assertEqual(repr(Point.x), "_tuplegetter(0, 'Alias for field number 0')") 439 self.assertEqual(repr(Point.y), "_tuplegetter(1, 'Alias for field number 1')") 440 441 Point.x.__doc__ = 'The x-coordinate' 442 Point.y.__doc__ = 'The y-coordinate' 443 444 self.assertEqual(repr(Point.x), "_tuplegetter(0, 'The x-coordinate')") 445 self.assertEqual(repr(Point.y), "_tuplegetter(1, 'The y-coordinate')") 446 447 def test_name_fixer(self): 448 for spec, renamed in [ 449 [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char 450 [('abc', 'class'), ('abc', '_1')], # field has keyword 451 [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit 452 [('abc', '_efg'), ('abc', '_1')], # field with leading underscore 453 [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field 454 [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space 455 ]: 456 self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) 457 458 def test_module_parameter(self): 459 NT = namedtuple('NT', ['x', 'y'], module=collections) 460 self.assertEqual(NT.__module__, collections) 461 462 def test_instance(self): 463 Point = namedtuple('Point', 'x y') 464 p = Point(11, 22) 465 self.assertEqual(p, Point(x=11, y=22)) 466 self.assertEqual(p, Point(11, y=22)) 467 self.assertEqual(p, Point(y=22, x=11)) 468 self.assertEqual(p, Point(*(11, 22))) 469 self.assertEqual(p, Point(**dict(x=11, y=22))) 470 self.assertRaises(TypeError, Point, 1) # too few args 471 self.assertRaises(TypeError, Point, 1, 2, 3) # too many args 472 with self.assertRaises(TypeError): # wrong keyword argument 473 Point(XXX=1, y=2) 474 with self.assertRaises(TypeError): # missing keyword argument 475 Point(x=1) 476 self.assertEqual(repr(p), 'Point(x=11, y=22)') 477 self.assertNotIn('__weakref__', dir(p)) 478 self.assertEqual(p, Point._make([11, 22])) # test _make classmethod 479 self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute 480 self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method 481 self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method 482 483 try: 484 p._replace(x=1, error=2) 485 except ValueError: 486 pass 487 else: 488 self._fail('Did not detect an incorrect fieldname') 489 490 # verify that field string can have commas 491 Point = namedtuple('Point', 'x, y') 492 p = Point(x=11, y=22) 493 self.assertEqual(repr(p), 'Point(x=11, y=22)') 494 495 # verify that fieldspec can be a non-string sequence 496 Point = namedtuple('Point', ('x', 'y')) 497 p = Point(x=11, y=22) 498 self.assertEqual(repr(p), 'Point(x=11, y=22)') 499 500 def test_tupleness(self): 501 Point = namedtuple('Point', 'x y') 502 p = Point(11, 22) 503 504 self.assertIsInstance(p, tuple) 505 self.assertEqual(p, (11, 22)) # matches a real tuple 506 self.assertEqual(tuple(p), (11, 22)) # coercible to a real tuple 507 self.assertEqual(list(p), [11, 22]) # coercible to a list 508 self.assertEqual(max(p), 22) # iterable 509 self.assertEqual(max(*p), 22) # star-able 510 x, y = p 511 self.assertEqual(p, (x, y)) # unpacks like a tuple 512 self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple 513 with self.assertRaises(IndexError): 514 p[3] 515 self.assertEqual(p[-1], 22) 516 self.assertEqual(hash(p), hash((11, 22))) 517 518 self.assertEqual(p.x, x) 519 self.assertEqual(p.y, y) 520 with self.assertRaises(AttributeError): 521 p.z 522 523 def test_odd_sizes(self): 524 Zero = namedtuple('Zero', '') 525 self.assertEqual(Zero(), ()) 526 self.assertEqual(Zero._make([]), ()) 527 self.assertEqual(repr(Zero()), 'Zero()') 528 self.assertEqual(Zero()._asdict(), {}) 529 self.assertEqual(Zero()._fields, ()) 530 531 Dot = namedtuple('Dot', 'd') 532 self.assertEqual(Dot(1), (1,)) 533 self.assertEqual(Dot._make([1]), (1,)) 534 self.assertEqual(Dot(1).d, 1) 535 self.assertEqual(repr(Dot(1)), 'Dot(d=1)') 536 self.assertEqual(Dot(1)._asdict(), {'d':1}) 537 self.assertEqual(Dot(1)._replace(d=999), (999,)) 538 self.assertEqual(Dot(1)._fields, ('d',)) 539 540 n = 5000 541 names = list(set(''.join([choice(string.ascii_letters) 542 for j in range(10)]) for i in range(n))) 543 n = len(names) 544 Big = namedtuple('Big', names) 545 b = Big(*range(n)) 546 self.assertEqual(b, tuple(range(n))) 547 self.assertEqual(Big._make(range(n)), tuple(range(n))) 548 for pos, name in enumerate(names): 549 self.assertEqual(getattr(b, name), pos) 550 repr(b) # make sure repr() doesn't blow-up 551 d = b._asdict() 552 d_expected = dict(zip(names, range(n))) 553 self.assertEqual(d, d_expected) 554 b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)])) 555 b2_expected = list(range(n)) 556 b2_expected[1] = 999 557 b2_expected[-5] = 42 558 self.assertEqual(b2, tuple(b2_expected)) 559 self.assertEqual(b._fields, tuple(names)) 560 561 def test_pickle(self): 562 p = TestNT(x=10, y=20, z=30) 563 for module in (pickle,): 564 loads = getattr(module, 'loads') 565 dumps = getattr(module, 'dumps') 566 for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): 567 q = loads(dumps(p, protocol)) 568 self.assertEqual(p, q) 569 self.assertEqual(p._fields, q._fields) 570 self.assertNotIn(b'OrderedDict', dumps(p, protocol)) 571 572 def test_copy(self): 573 p = TestNT(x=10, y=20, z=30) 574 for copier in copy.copy, copy.deepcopy: 575 q = copier(p) 576 self.assertEqual(p, q) 577 self.assertEqual(p._fields, q._fields) 578 579 def test_name_conflicts(self): 580 # Some names like "self", "cls", "tuple", "itemgetter", and "property" 581 # failed when used as field names. Test to make sure these now work. 582 T = namedtuple('T', 'itemgetter property self cls tuple') 583 t = T(1, 2, 3, 4, 5) 584 self.assertEqual(t, (1,2,3,4,5)) 585 newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50) 586 self.assertEqual(newt, (10,20,30,40,50)) 587 588 # Broader test of all interesting names taken from the code, old 589 # template, and an example 590 words = {'Alias', 'At', 'AttributeError', 'Build', 'Bypass', 'Create', 591 'Encountered', 'Expected', 'Field', 'For', 'Got', 'Helper', 592 'IronPython', 'Jython', 'KeyError', 'Make', 'Modify', 'Note', 593 'OrderedDict', 'Point', 'Return', 'Returns', 'Type', 'TypeError', 594 'Used', 'Validate', 'ValueError', 'Variables', 'a', 'accessible', 'add', 595 'added', 'all', 'also', 'an', 'arg_list', 'args', 'arguments', 596 'automatically', 'be', 'build', 'builtins', 'but', 'by', 'cannot', 597 'class_namespace', 'classmethod', 'cls', 'collections', 'convert', 598 'copy', 'created', 'creation', 'd', 'debugging', 'defined', 'dict', 599 'dictionary', 'doc', 'docstring', 'docstrings', 'duplicate', 'effect', 600 'either', 'enumerate', 'environments', 'error', 'example', 'exec', 'f', 601 'f_globals', 'field', 'field_names', 'fields', 'formatted', 'frame', 602 'function', 'functions', 'generate', 'get', 'getter', 'got', 'greater', 603 'has', 'help', 'identifiers', 'index', 'indexable', 'instance', 604 'instantiate', 'interning', 'introspection', 'isidentifier', 605 'isinstance', 'itemgetter', 'iterable', 'join', 'keyword', 'keywords', 606 'kwds', 'len', 'like', 'list', 'map', 'maps', 'message', 'metadata', 607 'method', 'methods', 'module', 'module_name', 'must', 'name', 'named', 608 'namedtuple', 'namedtuple_', 'names', 'namespace', 'needs', 'new', 609 'nicely', 'num_fields', 'number', 'object', 'of', 'operator', 'option', 610 'p', 'particular', 'pickle', 'pickling', 'plain', 'pop', 'positional', 611 'property', 'r', 'regular', 'rename', 'replace', 'replacing', 'repr', 612 'repr_fmt', 'representation', 'result', 'reuse_itemgetter', 's', 'seen', 613 'self', 'sequence', 'set', 'side', 'specified', 'split', 'start', 614 'startswith', 'step', 'str', 'string', 'strings', 'subclass', 'sys', 615 'targets', 'than', 'the', 'their', 'this', 'to', 'tuple', 'tuple_new', 616 'type', 'typename', 'underscore', 'unexpected', 'unpack', 'up', 'use', 617 'used', 'user', 'valid', 'values', 'variable', 'verbose', 'where', 618 'which', 'work', 'x', 'y', 'z', 'zip'} 619 T = namedtuple('T', words) 620 # test __new__ 621 values = tuple(range(len(words))) 622 t = T(*values) 623 self.assertEqual(t, values) 624 t = T(**dict(zip(T._fields, values))) 625 self.assertEqual(t, values) 626 # test _make 627 t = T._make(values) 628 self.assertEqual(t, values) 629 # exercise __repr__ 630 repr(t) 631 # test _asdict 632 self.assertEqual(t._asdict(), dict(zip(T._fields, values))) 633 # test _replace 634 t = T._make(values) 635 newvalues = tuple(v*10 for v in values) 636 newt = t._replace(**dict(zip(T._fields, newvalues))) 637 self.assertEqual(newt, newvalues) 638 # test _fields 639 self.assertEqual(T._fields, tuple(words)) 640 # test __getnewargs__ 641 self.assertEqual(t.__getnewargs__(), values) 642 643 def test_repr(self): 644 A = namedtuple('A', 'x') 645 self.assertEqual(repr(A(1)), 'A(x=1)') 646 # repr should show the name of the subclass 647 class B(A): 648 pass 649 self.assertEqual(repr(B(1)), 'B(x=1)') 650 651 def test_keyword_only_arguments(self): 652 # See issue 25628 653 with self.assertRaises(TypeError): 654 NT = namedtuple('NT', ['x', 'y'], True) 655 656 NT = namedtuple('NT', ['abc', 'def'], rename=True) 657 self.assertEqual(NT._fields, ('abc', '_1')) 658 with self.assertRaises(TypeError): 659 NT = namedtuple('NT', ['abc', 'def'], False, True) 660 661 def test_namedtuple_subclass_issue_24931(self): 662 class Point(namedtuple('_Point', ['x', 'y'])): 663 pass 664 665 a = Point(3, 4) 666 self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)])) 667 668 a.w = 5 669 self.assertEqual(a.__dict__, {'w': 5}) 670 671 @support.cpython_only 672 def test_field_descriptor(self): 673 Point = namedtuple('Point', 'x y') 674 p = Point(11, 22) 675 self.assertTrue(inspect.isdatadescriptor(Point.x)) 676 self.assertEqual(Point.x.__get__(p), 11) 677 self.assertRaises(AttributeError, Point.x.__set__, p, 33) 678 self.assertRaises(AttributeError, Point.x.__delete__, p) 679 680 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 681 with self.subTest(proto=proto): 682 class NewPoint(tuple): 683 x = pickle.loads(pickle.dumps(Point.x, proto)) 684 y = pickle.loads(pickle.dumps(Point.y, proto)) 685 686 np = NewPoint([1, 2]) 687 688 self.assertEqual(np.x, 1) 689 self.assertEqual(np.y, 2) 690 691 def test_new_builtins_issue_43102(self): 692 obj = namedtuple('C', ()) 693 new_func = obj.__new__ 694 self.assertEqual(new_func.__globals__['__builtins__'], {}) 695 self.assertEqual(new_func.__builtins__, {}) 696 697 def test_match_args(self): 698 Point = namedtuple('Point', 'x y') 699 self.assertEqual(Point.__match_args__, ('x', 'y')) 700 701 def test_non_generic_subscript(self): 702 # For backward compatibility, subscription works 703 # on arbitrary named tuple types. 704 Group = collections.namedtuple('Group', 'key group') 705 A = Group[int, list[int]] 706 self.assertEqual(A.__origin__, Group) 707 self.assertEqual(A.__parameters__, ()) 708 self.assertEqual(A.__args__, (int, list[int])) 709 a = A(1, [2]) 710 self.assertIs(type(a), Group) 711 self.assertEqual(a, (1, [2])) 712 713 714################################################################################ 715### Abstract Base Classes 716################################################################################ 717 718class ABCTestCase(unittest.TestCase): 719 720 def validate_abstract_methods(self, abc, *names): 721 methodstubs = dict.fromkeys(names, lambda s, *args: 0) 722 723 # everything should work will all required methods are present 724 C = type('C', (abc,), methodstubs) 725 C() 726 727 # instantiation should fail if a required method is missing 728 for name in names: 729 stubs = methodstubs.copy() 730 del stubs[name] 731 C = type('C', (abc,), stubs) 732 self.assertRaises(TypeError, C, name) 733 734 def validate_isinstance(self, abc, name): 735 stub = lambda s, *args: 0 736 737 C = type('C', (object,), {'__hash__': None}) 738 setattr(C, name, stub) 739 self.assertIsInstance(C(), abc) 740 self.assertTrue(issubclass(C, abc)) 741 742 C = type('C', (object,), {'__hash__': None}) 743 self.assertNotIsInstance(C(), abc) 744 self.assertFalse(issubclass(C, abc)) 745 746 def validate_comparison(self, instance): 747 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] 748 operators = {} 749 for op in ops: 750 name = '__' + op + '__' 751 operators[name] = getattr(operator, name) 752 753 class Other: 754 def __init__(self): 755 self.right_side = False 756 def __eq__(self, other): 757 self.right_side = True 758 return True 759 __lt__ = __eq__ 760 __gt__ = __eq__ 761 __le__ = __eq__ 762 __ge__ = __eq__ 763 __ne__ = __eq__ 764 __ror__ = __eq__ 765 __rand__ = __eq__ 766 __rxor__ = __eq__ 767 __rsub__ = __eq__ 768 769 for name, op in operators.items(): 770 if not hasattr(instance, name): 771 continue 772 other = Other() 773 op(instance, other) 774 self.assertTrue(other.right_side,'Right side not called for %s.%s' 775 % (type(instance), name)) 776 777def _test_gen(): 778 yield 779 780class TestOneTrickPonyABCs(ABCTestCase): 781 782 def test_Awaitable(self): 783 def gen(): 784 yield 785 786 @types.coroutine 787 def coro(): 788 yield 789 790 async def new_coro(): 791 pass 792 793 class Bar: 794 def __await__(self): 795 yield 796 797 class MinimalCoro(Coroutine): 798 def send(self, value): 799 return value 800 def throw(self, typ, val=None, tb=None): 801 super().throw(typ, val, tb) 802 def __await__(self): 803 yield 804 805 self.validate_abstract_methods(Awaitable, '__await__') 806 807 non_samples = [None, int(), gen(), object()] 808 for x in non_samples: 809 self.assertNotIsInstance(x, Awaitable) 810 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) 811 812 samples = [Bar(), MinimalCoro()] 813 for x in samples: 814 self.assertIsInstance(x, Awaitable) 815 self.assertTrue(issubclass(type(x), Awaitable)) 816 817 c = coro() 818 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE 819 # flag don't have '__await__' method, hence can't be instances 820 # of Awaitable. Use inspect.isawaitable to detect them. 821 self.assertNotIsInstance(c, Awaitable) 822 823 c = new_coro() 824 self.assertIsInstance(c, Awaitable) 825 c.close() # avoid RuntimeWarning that coro() was not awaited 826 827 class CoroLike: pass 828 Coroutine.register(CoroLike) 829 self.assertTrue(isinstance(CoroLike(), Awaitable)) 830 self.assertTrue(issubclass(CoroLike, Awaitable)) 831 CoroLike = None 832 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache 833 834 def test_Coroutine(self): 835 def gen(): 836 yield 837 838 @types.coroutine 839 def coro(): 840 yield 841 842 async def new_coro(): 843 pass 844 845 class Bar: 846 def __await__(self): 847 yield 848 849 class MinimalCoro(Coroutine): 850 def send(self, value): 851 return value 852 def throw(self, typ, val=None, tb=None): 853 super().throw(typ, val, tb) 854 def __await__(self): 855 yield 856 857 self.validate_abstract_methods(Coroutine, '__await__', 'send', 'throw') 858 859 non_samples = [None, int(), gen(), object(), Bar()] 860 for x in non_samples: 861 self.assertNotIsInstance(x, Coroutine) 862 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) 863 864 samples = [MinimalCoro()] 865 for x in samples: 866 self.assertIsInstance(x, Awaitable) 867 self.assertTrue(issubclass(type(x), Awaitable)) 868 869 c = coro() 870 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE 871 # flag don't have '__await__' method, hence can't be instances 872 # of Coroutine. Use inspect.isawaitable to detect them. 873 self.assertNotIsInstance(c, Coroutine) 874 875 c = new_coro() 876 self.assertIsInstance(c, Coroutine) 877 c.close() # avoid RuntimeWarning that coro() was not awaited 878 879 class CoroLike: 880 def send(self, value): 881 pass 882 def throw(self, typ, val=None, tb=None): 883 pass 884 def close(self): 885 pass 886 def __await__(self): 887 pass 888 self.assertTrue(isinstance(CoroLike(), Coroutine)) 889 self.assertTrue(issubclass(CoroLike, Coroutine)) 890 891 class CoroLike: 892 def send(self, value): 893 pass 894 def close(self): 895 pass 896 def __await__(self): 897 pass 898 self.assertFalse(isinstance(CoroLike(), Coroutine)) 899 self.assertFalse(issubclass(CoroLike, Coroutine)) 900 901 def test_Hashable(self): 902 # Check some non-hashables 903 non_samples = [bytearray(), list(), set(), dict()] 904 for x in non_samples: 905 self.assertNotIsInstance(x, Hashable) 906 self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) 907 # Check some hashables 908 samples = [None, 909 int(), float(), complex(), 910 str(), 911 tuple(), frozenset(), 912 int, list, object, type, bytes() 913 ] 914 for x in samples: 915 self.assertIsInstance(x, Hashable) 916 self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) 917 self.assertRaises(TypeError, Hashable) 918 # Check direct subclassing 919 class H(Hashable): 920 def __hash__(self): 921 return super().__hash__() 922 self.assertEqual(hash(H()), 0) 923 self.assertFalse(issubclass(int, H)) 924 self.validate_abstract_methods(Hashable, '__hash__') 925 self.validate_isinstance(Hashable, '__hash__') 926 927 def test_AsyncIterable(self): 928 class AI: 929 def __aiter__(self): 930 return self 931 self.assertTrue(isinstance(AI(), AsyncIterable)) 932 self.assertTrue(issubclass(AI, AsyncIterable)) 933 # Check some non-iterables 934 non_samples = [None, object, []] 935 for x in non_samples: 936 self.assertNotIsInstance(x, AsyncIterable) 937 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) 938 self.validate_abstract_methods(AsyncIterable, '__aiter__') 939 self.validate_isinstance(AsyncIterable, '__aiter__') 940 941 def test_AsyncIterator(self): 942 class AI: 943 def __aiter__(self): 944 return self 945 async def __anext__(self): 946 raise StopAsyncIteration 947 self.assertTrue(isinstance(AI(), AsyncIterator)) 948 self.assertTrue(issubclass(AI, AsyncIterator)) 949 non_samples = [None, object, []] 950 # Check some non-iterables 951 for x in non_samples: 952 self.assertNotIsInstance(x, AsyncIterator) 953 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) 954 # Similarly to regular iterators (see issue 10565) 955 class AnextOnly: 956 async def __anext__(self): 957 raise StopAsyncIteration 958 self.assertNotIsInstance(AnextOnly(), AsyncIterator) 959 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') 960 961 def test_Iterable(self): 962 # Check some non-iterables 963 non_samples = [None, 42, 3.14, 1j] 964 for x in non_samples: 965 self.assertNotIsInstance(x, Iterable) 966 self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) 967 # Check some iterables 968 samples = [bytes(), str(), 969 tuple(), list(), set(), frozenset(), dict(), 970 dict().keys(), dict().items(), dict().values(), 971 _test_gen(), 972 (x for x in []), 973 ] 974 for x in samples: 975 self.assertIsInstance(x, Iterable) 976 self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) 977 # Check direct subclassing 978 class I(Iterable): 979 def __iter__(self): 980 return super().__iter__() 981 self.assertEqual(list(I()), []) 982 self.assertFalse(issubclass(str, I)) 983 self.validate_abstract_methods(Iterable, '__iter__') 984 self.validate_isinstance(Iterable, '__iter__') 985 # Check None blocking 986 class It: 987 def __iter__(self): return iter([]) 988 class ItBlocked(It): 989 __iter__ = None 990 self.assertTrue(issubclass(It, Iterable)) 991 self.assertTrue(isinstance(It(), Iterable)) 992 self.assertFalse(issubclass(ItBlocked, Iterable)) 993 self.assertFalse(isinstance(ItBlocked(), Iterable)) 994 995 def test_Reversible(self): 996 # Check some non-reversibles 997 non_samples = [None, 42, 3.14, 1j, set(), frozenset()] 998 for x in non_samples: 999 self.assertNotIsInstance(x, Reversible) 1000 self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) 1001 # Check some non-reversible iterables 1002 non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])] 1003 for x in non_reversibles: 1004 self.assertNotIsInstance(x, Reversible) 1005 self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) 1006 # Check some reversible iterables 1007 samples = [bytes(), str(), tuple(), list(), OrderedDict(), 1008 OrderedDict().keys(), OrderedDict().items(), 1009 OrderedDict().values(), Counter(), Counter().keys(), 1010 Counter().items(), Counter().values(), dict(), 1011 dict().keys(), dict().items(), dict().values()] 1012 for x in samples: 1013 self.assertIsInstance(x, Reversible) 1014 self.assertTrue(issubclass(type(x), Reversible), repr(type(x))) 1015 # Check also Mapping, MutableMapping, and Sequence 1016 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence)) 1017 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping)) 1018 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping)) 1019 # Check direct subclassing 1020 class R(Reversible): 1021 def __iter__(self): 1022 return iter(list()) 1023 def __reversed__(self): 1024 return iter(list()) 1025 self.assertEqual(list(reversed(R())), []) 1026 self.assertFalse(issubclass(float, R)) 1027 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__') 1028 # Check reversible non-iterable (which is not Reversible) 1029 class RevNoIter: 1030 def __reversed__(self): return reversed([]) 1031 class RevPlusIter(RevNoIter): 1032 def __iter__(self): return iter([]) 1033 self.assertFalse(issubclass(RevNoIter, Reversible)) 1034 self.assertFalse(isinstance(RevNoIter(), Reversible)) 1035 self.assertTrue(issubclass(RevPlusIter, Reversible)) 1036 self.assertTrue(isinstance(RevPlusIter(), Reversible)) 1037 # Check None blocking 1038 class Rev: 1039 def __iter__(self): return iter([]) 1040 def __reversed__(self): return reversed([]) 1041 class RevItBlocked(Rev): 1042 __iter__ = None 1043 class RevRevBlocked(Rev): 1044 __reversed__ = None 1045 self.assertTrue(issubclass(Rev, Reversible)) 1046 self.assertTrue(isinstance(Rev(), Reversible)) 1047 self.assertFalse(issubclass(RevItBlocked, Reversible)) 1048 self.assertFalse(isinstance(RevItBlocked(), Reversible)) 1049 self.assertFalse(issubclass(RevRevBlocked, Reversible)) 1050 self.assertFalse(isinstance(RevRevBlocked(), Reversible)) 1051 1052 def test_Collection(self): 1053 # Check some non-collections 1054 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x] 1055 for x in non_collections: 1056 self.assertNotIsInstance(x, Collection) 1057 self.assertFalse(issubclass(type(x), Collection), repr(type(x))) 1058 # Check some non-collection iterables 1059 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()), 1060 (x for x in [])] 1061 for x in non_col_iterables: 1062 self.assertNotIsInstance(x, Collection) 1063 self.assertFalse(issubclass(type(x), Collection), repr(type(x))) 1064 # Check some collections 1065 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(), 1066 list(), dict().keys(), dict().items(), dict().values()] 1067 for x in samples: 1068 self.assertIsInstance(x, Collection) 1069 self.assertTrue(issubclass(type(x), Collection), repr(type(x))) 1070 # Check also Mapping, MutableMapping, etc. 1071 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence)) 1072 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping)) 1073 self.assertTrue(issubclass(MutableMapping, Collection), 1074 repr(MutableMapping)) 1075 self.assertTrue(issubclass(Set, Collection), repr(Set)) 1076 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet)) 1077 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet)) 1078 # Check direct subclassing 1079 class Col(Collection): 1080 def __iter__(self): 1081 return iter(list()) 1082 def __len__(self): 1083 return 0 1084 def __contains__(self, item): 1085 return False 1086 class DerCol(Col): pass 1087 self.assertEqual(list(iter(Col())), []) 1088 self.assertFalse(issubclass(list, Col)) 1089 self.assertFalse(issubclass(set, Col)) 1090 self.assertFalse(issubclass(float, Col)) 1091 self.assertEqual(list(iter(DerCol())), []) 1092 self.assertFalse(issubclass(list, DerCol)) 1093 self.assertFalse(issubclass(set, DerCol)) 1094 self.assertFalse(issubclass(float, DerCol)) 1095 self.validate_abstract_methods(Collection, '__len__', '__iter__', 1096 '__contains__') 1097 # Check sized container non-iterable (which is not Collection) etc. 1098 class ColNoIter: 1099 def __len__(self): return 0 1100 def __contains__(self, item): return False 1101 class ColNoSize: 1102 def __iter__(self): return iter([]) 1103 def __contains__(self, item): return False 1104 class ColNoCont: 1105 def __iter__(self): return iter([]) 1106 def __len__(self): return 0 1107 self.assertFalse(issubclass(ColNoIter, Collection)) 1108 self.assertFalse(isinstance(ColNoIter(), Collection)) 1109 self.assertFalse(issubclass(ColNoSize, Collection)) 1110 self.assertFalse(isinstance(ColNoSize(), Collection)) 1111 self.assertFalse(issubclass(ColNoCont, Collection)) 1112 self.assertFalse(isinstance(ColNoCont(), Collection)) 1113 # Check None blocking 1114 class SizeBlock: 1115 def __iter__(self): return iter([]) 1116 def __contains__(self): return False 1117 __len__ = None 1118 class IterBlock: 1119 def __len__(self): return 0 1120 def __contains__(self): return True 1121 __iter__ = None 1122 self.assertFalse(issubclass(SizeBlock, Collection)) 1123 self.assertFalse(isinstance(SizeBlock(), Collection)) 1124 self.assertFalse(issubclass(IterBlock, Collection)) 1125 self.assertFalse(isinstance(IterBlock(), Collection)) 1126 # Check None blocking in subclass 1127 class ColImpl: 1128 def __iter__(self): 1129 return iter(list()) 1130 def __len__(self): 1131 return 0 1132 def __contains__(self, item): 1133 return False 1134 class NonCol(ColImpl): 1135 __contains__ = None 1136 self.assertFalse(issubclass(NonCol, Collection)) 1137 self.assertFalse(isinstance(NonCol(), Collection)) 1138 1139 1140 def test_Iterator(self): 1141 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] 1142 for x in non_samples: 1143 self.assertNotIsInstance(x, Iterator) 1144 self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) 1145 samples = [iter(bytes()), iter(str()), 1146 iter(tuple()), iter(list()), iter(dict()), 1147 iter(set()), iter(frozenset()), 1148 iter(dict().keys()), iter(dict().items()), 1149 iter(dict().values()), 1150 _test_gen(), 1151 (x for x in []), 1152 ] 1153 for x in samples: 1154 self.assertIsInstance(x, Iterator) 1155 self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) 1156 self.validate_abstract_methods(Iterator, '__next__', '__iter__') 1157 1158 # Issue 10565 1159 class NextOnly: 1160 def __next__(self): 1161 yield 1 1162 return 1163 self.assertNotIsInstance(NextOnly(), Iterator) 1164 1165 def test_Generator(self): 1166 class NonGen1: 1167 def __iter__(self): return self 1168 def __next__(self): return None 1169 def close(self): pass 1170 def throw(self, typ, val=None, tb=None): pass 1171 1172 class NonGen2: 1173 def __iter__(self): return self 1174 def __next__(self): return None 1175 def close(self): pass 1176 def send(self, value): return value 1177 1178 class NonGen3: 1179 def close(self): pass 1180 def send(self, value): return value 1181 def throw(self, typ, val=None, tb=None): pass 1182 1183 non_samples = [ 1184 None, 42, 3.14, 1j, b"", "", (), [], {}, set(), 1185 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] 1186 for x in non_samples: 1187 self.assertNotIsInstance(x, Generator) 1188 self.assertFalse(issubclass(type(x), Generator), repr(type(x))) 1189 1190 class Gen: 1191 def __iter__(self): return self 1192 def __next__(self): return None 1193 def close(self): pass 1194 def send(self, value): return value 1195 def throw(self, typ, val=None, tb=None): pass 1196 1197 class MinimalGen(Generator): 1198 def send(self, value): 1199 return value 1200 def throw(self, typ, val=None, tb=None): 1201 super().throw(typ, val, tb) 1202 1203 def gen(): 1204 yield 1 1205 1206 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()] 1207 for x in samples: 1208 self.assertIsInstance(x, Iterator) 1209 self.assertIsInstance(x, Generator) 1210 self.assertTrue(issubclass(type(x), Generator), repr(type(x))) 1211 self.validate_abstract_methods(Generator, 'send', 'throw') 1212 1213 # mixin tests 1214 mgen = MinimalGen() 1215 self.assertIs(mgen, iter(mgen)) 1216 self.assertIs(mgen.send(None), next(mgen)) 1217 self.assertEqual(2, mgen.send(2)) 1218 self.assertIsNone(mgen.close()) 1219 self.assertRaises(ValueError, mgen.throw, ValueError) 1220 self.assertRaisesRegex(ValueError, "^huhu$", 1221 mgen.throw, ValueError, ValueError("huhu")) 1222 self.assertRaises(StopIteration, mgen.throw, StopIteration()) 1223 1224 class FailOnClose(Generator): 1225 def send(self, value): return value 1226 def throw(self, *args): raise ValueError 1227 1228 self.assertRaises(ValueError, FailOnClose().close) 1229 1230 class IgnoreGeneratorExit(Generator): 1231 def send(self, value): return value 1232 def throw(self, *args): pass 1233 1234 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close) 1235 1236 def test_AsyncGenerator(self): 1237 class NonAGen1: 1238 def __aiter__(self): return self 1239 def __anext__(self): return None 1240 def aclose(self): pass 1241 def athrow(self, typ, val=None, tb=None): pass 1242 1243 class NonAGen2: 1244 def __aiter__(self): return self 1245 def __anext__(self): return None 1246 def aclose(self): pass 1247 def asend(self, value): return value 1248 1249 class NonAGen3: 1250 def aclose(self): pass 1251 def asend(self, value): return value 1252 def athrow(self, typ, val=None, tb=None): pass 1253 1254 non_samples = [ 1255 None, 42, 3.14, 1j, b"", "", (), [], {}, set(), 1256 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()] 1257 for x in non_samples: 1258 self.assertNotIsInstance(x, AsyncGenerator) 1259 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x))) 1260 1261 class Gen: 1262 def __aiter__(self): return self 1263 async def __anext__(self): return None 1264 async def aclose(self): pass 1265 async def asend(self, value): return value 1266 async def athrow(self, typ, val=None, tb=None): pass 1267 1268 class MinimalAGen(AsyncGenerator): 1269 async def asend(self, value): 1270 return value 1271 async def athrow(self, typ, val=None, tb=None): 1272 await super().athrow(typ, val, tb) 1273 1274 async def gen(): 1275 yield 1 1276 1277 samples = [gen(), Gen(), MinimalAGen()] 1278 for x in samples: 1279 self.assertIsInstance(x, AsyncIterator) 1280 self.assertIsInstance(x, AsyncGenerator) 1281 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x))) 1282 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow') 1283 1284 def run_async(coro): 1285 result = None 1286 while True: 1287 try: 1288 coro.send(None) 1289 except StopIteration as ex: 1290 result = ex.args[0] if ex.args else None 1291 break 1292 return result 1293 1294 # mixin tests 1295 mgen = MinimalAGen() 1296 self.assertIs(mgen, mgen.__aiter__()) 1297 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__())) 1298 self.assertEqual(2, run_async(mgen.asend(2))) 1299 self.assertIsNone(run_async(mgen.aclose())) 1300 with self.assertRaises(ValueError): 1301 run_async(mgen.athrow(ValueError)) 1302 1303 class FailOnClose(AsyncGenerator): 1304 async def asend(self, value): return value 1305 async def athrow(self, *args): raise ValueError 1306 1307 with self.assertRaises(ValueError): 1308 run_async(FailOnClose().aclose()) 1309 1310 class IgnoreGeneratorExit(AsyncGenerator): 1311 async def asend(self, value): return value 1312 async def athrow(self, *args): pass 1313 1314 with self.assertRaises(RuntimeError): 1315 run_async(IgnoreGeneratorExit().aclose()) 1316 1317 def test_Sized(self): 1318 non_samples = [None, 42, 3.14, 1j, 1319 _test_gen(), 1320 (x for x in []), 1321 ] 1322 for x in non_samples: 1323 self.assertNotIsInstance(x, Sized) 1324 self.assertFalse(issubclass(type(x), Sized), repr(type(x))) 1325 samples = [bytes(), str(), 1326 tuple(), list(), set(), frozenset(), dict(), 1327 dict().keys(), dict().items(), dict().values(), 1328 ] 1329 for x in samples: 1330 self.assertIsInstance(x, Sized) 1331 self.assertTrue(issubclass(type(x), Sized), repr(type(x))) 1332 self.validate_abstract_methods(Sized, '__len__') 1333 self.validate_isinstance(Sized, '__len__') 1334 1335 def test_Container(self): 1336 non_samples = [None, 42, 3.14, 1j, 1337 _test_gen(), 1338 (x for x in []), 1339 ] 1340 for x in non_samples: 1341 self.assertNotIsInstance(x, Container) 1342 self.assertFalse(issubclass(type(x), Container), repr(type(x))) 1343 samples = [bytes(), str(), 1344 tuple(), list(), set(), frozenset(), dict(), 1345 dict().keys(), dict().items(), 1346 ] 1347 for x in samples: 1348 self.assertIsInstance(x, Container) 1349 self.assertTrue(issubclass(type(x), Container), repr(type(x))) 1350 self.validate_abstract_methods(Container, '__contains__') 1351 self.validate_isinstance(Container, '__contains__') 1352 1353 def test_Callable(self): 1354 non_samples = [None, 42, 3.14, 1j, 1355 "", b"", (), [], {}, set(), 1356 _test_gen(), 1357 (x for x in []), 1358 ] 1359 for x in non_samples: 1360 self.assertNotIsInstance(x, Callable) 1361 self.assertFalse(issubclass(type(x), Callable), repr(type(x))) 1362 samples = [lambda: None, 1363 type, int, object, 1364 len, 1365 list.append, [].append, 1366 ] 1367 for x in samples: 1368 self.assertIsInstance(x, Callable) 1369 self.assertTrue(issubclass(type(x), Callable), repr(type(x))) 1370 self.validate_abstract_methods(Callable, '__call__') 1371 self.validate_isinstance(Callable, '__call__') 1372 1373 def test_direct_subclassing(self): 1374 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: 1375 class C(B): 1376 pass 1377 self.assertTrue(issubclass(C, B)) 1378 self.assertFalse(issubclass(int, C)) 1379 1380 def test_registration(self): 1381 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: 1382 class C: 1383 __hash__ = None # Make sure it isn't hashable by default 1384 self.assertFalse(issubclass(C, B), B.__name__) 1385 B.register(C) 1386 self.assertTrue(issubclass(C, B)) 1387 1388class WithSet(MutableSet): 1389 1390 def __init__(self, it=()): 1391 self.data = set(it) 1392 1393 def __len__(self): 1394 return len(self.data) 1395 1396 def __iter__(self): 1397 return iter(self.data) 1398 1399 def __contains__(self, item): 1400 return item in self.data 1401 1402 def add(self, item): 1403 self.data.add(item) 1404 1405 def discard(self, item): 1406 self.data.discard(item) 1407 1408class TestCollectionABCs(ABCTestCase): 1409 1410 # XXX For now, we only test some virtual inheritance properties. 1411 # We should also test the proper behavior of the collection ABCs 1412 # as real base classes or mix-in classes. 1413 1414 def test_Set(self): 1415 for sample in [set, frozenset]: 1416 self.assertIsInstance(sample(), Set) 1417 self.assertTrue(issubclass(sample, Set)) 1418 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') 1419 class MySet(Set): 1420 def __contains__(self, x): 1421 return False 1422 def __len__(self): 1423 return 0 1424 def __iter__(self): 1425 return iter([]) 1426 self.validate_comparison(MySet()) 1427 1428 def test_hash_Set(self): 1429 class OneTwoThreeSet(Set): 1430 def __init__(self): 1431 self.contents = [1, 2, 3] 1432 def __contains__(self, x): 1433 return x in self.contents 1434 def __len__(self): 1435 return len(self.contents) 1436 def __iter__(self): 1437 return iter(self.contents) 1438 def __hash__(self): 1439 return self._hash() 1440 a, b = OneTwoThreeSet(), OneTwoThreeSet() 1441 self.assertTrue(hash(a) == hash(b)) 1442 1443 def test_isdisjoint_Set(self): 1444 class MySet(Set): 1445 def __init__(self, itr): 1446 self.contents = itr 1447 def __contains__(self, x): 1448 return x in self.contents 1449 def __iter__(self): 1450 return iter(self.contents) 1451 def __len__(self): 1452 return len([x for x in self.contents]) 1453 s1 = MySet((1, 2, 3)) 1454 s2 = MySet((4, 5, 6)) 1455 s3 = MySet((1, 5, 6)) 1456 self.assertTrue(s1.isdisjoint(s2)) 1457 self.assertFalse(s1.isdisjoint(s3)) 1458 1459 def test_equality_Set(self): 1460 class MySet(Set): 1461 def __init__(self, itr): 1462 self.contents = itr 1463 def __contains__(self, x): 1464 return x in self.contents 1465 def __iter__(self): 1466 return iter(self.contents) 1467 def __len__(self): 1468 return len([x for x in self.contents]) 1469 s1 = MySet((1,)) 1470 s2 = MySet((1, 2)) 1471 s3 = MySet((3, 4)) 1472 s4 = MySet((3, 4)) 1473 self.assertTrue(s2 > s1) 1474 self.assertTrue(s1 < s2) 1475 self.assertFalse(s2 <= s1) 1476 self.assertFalse(s2 <= s3) 1477 self.assertFalse(s1 >= s2) 1478 self.assertEqual(s3, s4) 1479 self.assertNotEqual(s2, s3) 1480 1481 def test_arithmetic_Set(self): 1482 class MySet(Set): 1483 def __init__(self, itr): 1484 self.contents = itr 1485 def __contains__(self, x): 1486 return x in self.contents 1487 def __iter__(self): 1488 return iter(self.contents) 1489 def __len__(self): 1490 return len([x for x in self.contents]) 1491 s1 = MySet((1, 2, 3)) 1492 s2 = MySet((3, 4, 5)) 1493 s3 = s1 & s2 1494 self.assertEqual(s3, MySet((3,))) 1495 1496 def test_MutableSet(self): 1497 self.assertIsInstance(set(), MutableSet) 1498 self.assertTrue(issubclass(set, MutableSet)) 1499 self.assertNotIsInstance(frozenset(), MutableSet) 1500 self.assertFalse(issubclass(frozenset, MutableSet)) 1501 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 1502 'add', 'discard') 1503 1504 def test_issue_5647(self): 1505 # MutableSet.__iand__ mutated the set during iteration 1506 s = WithSet('abcd') 1507 s &= WithSet('cdef') # This used to fail 1508 self.assertEqual(set(s), set('cd')) 1509 1510 def test_issue_4920(self): 1511 # MutableSet.pop() method did not work 1512 class MySet(MutableSet): 1513 __slots__=['__s'] 1514 def __init__(self,items=None): 1515 if items is None: 1516 items=[] 1517 self.__s=set(items) 1518 def __contains__(self,v): 1519 return v in self.__s 1520 def __iter__(self): 1521 return iter(self.__s) 1522 def __len__(self): 1523 return len(self.__s) 1524 def add(self,v): 1525 result=v not in self.__s 1526 self.__s.add(v) 1527 return result 1528 def discard(self,v): 1529 result=v in self.__s 1530 self.__s.discard(v) 1531 return result 1532 def __repr__(self): 1533 return "MySet(%s)" % repr(list(self)) 1534 items = [5,43,2,1] 1535 s = MySet(items) 1536 r = s.pop() 1537 self.assertEqual(len(s), len(items) - 1) 1538 self.assertNotIn(r, s) 1539 self.assertIn(r, items) 1540 1541 def test_issue8750(self): 1542 empty = WithSet() 1543 full = WithSet(range(10)) 1544 s = WithSet(full) 1545 s -= s 1546 self.assertEqual(s, empty) 1547 s = WithSet(full) 1548 s ^= s 1549 self.assertEqual(s, empty) 1550 s = WithSet(full) 1551 s &= s 1552 self.assertEqual(s, full) 1553 s |= s 1554 self.assertEqual(s, full) 1555 1556 def test_issue16373(self): 1557 # Recursion error comparing comparable and noncomparable 1558 # Set instances 1559 class MyComparableSet(Set): 1560 def __contains__(self, x): 1561 return False 1562 def __len__(self): 1563 return 0 1564 def __iter__(self): 1565 return iter([]) 1566 class MyNonComparableSet(Set): 1567 def __contains__(self, x): 1568 return False 1569 def __len__(self): 1570 return 0 1571 def __iter__(self): 1572 return iter([]) 1573 def __le__(self, x): 1574 return NotImplemented 1575 def __lt__(self, x): 1576 return NotImplemented 1577 1578 cs = MyComparableSet() 1579 ncs = MyNonComparableSet() 1580 self.assertFalse(ncs < cs) 1581 self.assertTrue(ncs <= cs) 1582 self.assertFalse(ncs > cs) 1583 self.assertTrue(ncs >= cs) 1584 1585 def test_issue26915(self): 1586 # Container membership test should check identity first 1587 class CustomSequence(Sequence): 1588 def __init__(self, seq): 1589 self._seq = seq 1590 def __getitem__(self, index): 1591 return self._seq[index] 1592 def __len__(self): 1593 return len(self._seq) 1594 1595 nan = float('nan') 1596 obj = support.NEVER_EQ 1597 seq = CustomSequence([nan, obj, nan]) 1598 containers = [ 1599 seq, 1600 ItemsView({1: nan, 2: obj}), 1601 KeysView({1: nan, 2: obj}), 1602 ValuesView({1: nan, 2: obj}) 1603 ] 1604 for container in containers: 1605 for elem in container: 1606 self.assertIn(elem, container) 1607 self.assertEqual(seq.index(nan), 0) 1608 self.assertEqual(seq.index(obj), 1) 1609 self.assertEqual(seq.count(nan), 2) 1610 self.assertEqual(seq.count(obj), 1) 1611 1612 def assertSameSet(self, s1, s2): 1613 # coerce both to a real set then check equality 1614 self.assertSetEqual(set(s1), set(s2)) 1615 1616 def test_Set_from_iterable(self): 1617 """Verify _from_iterable overridden to an instance method works.""" 1618 class SetUsingInstanceFromIterable(MutableSet): 1619 def __init__(self, values, created_by): 1620 if not created_by: 1621 raise ValueError(f'created_by must be specified') 1622 self.created_by = created_by 1623 self._values = set(values) 1624 1625 def _from_iterable(self, values): 1626 return type(self)(values, 'from_iterable') 1627 1628 def __contains__(self, value): 1629 return value in self._values 1630 1631 def __iter__(self): 1632 yield from self._values 1633 1634 def __len__(self): 1635 return len(self._values) 1636 1637 def add(self, value): 1638 self._values.add(value) 1639 1640 def discard(self, value): 1641 self._values.discard(value) 1642 1643 impl = SetUsingInstanceFromIterable([1, 2, 3], 'test') 1644 1645 actual = impl - {1} 1646 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1647 self.assertEqual('from_iterable', actual.created_by) 1648 self.assertEqual({2, 3}, actual) 1649 1650 actual = impl | {4} 1651 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1652 self.assertEqual('from_iterable', actual.created_by) 1653 self.assertEqual({1, 2, 3, 4}, actual) 1654 1655 actual = impl & {2} 1656 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1657 self.assertEqual('from_iterable', actual.created_by) 1658 self.assertEqual({2}, actual) 1659 1660 actual = impl ^ {3, 4} 1661 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1662 self.assertEqual('from_iterable', actual.created_by) 1663 self.assertEqual({1, 2, 4}, actual) 1664 1665 # NOTE: ixor'ing with a list is important here: internally, __ixor__ 1666 # only calls _from_iterable if the other value isn't already a Set. 1667 impl ^= [3, 4] 1668 self.assertIsInstance(impl, SetUsingInstanceFromIterable) 1669 self.assertEqual('test', impl.created_by) 1670 self.assertEqual({1, 2, 4}, impl) 1671 1672 def test_Set_interoperability_with_real_sets(self): 1673 # Issue: 8743 1674 class ListSet(Set): 1675 def __init__(self, elements=()): 1676 self.data = [] 1677 for elem in elements: 1678 if elem not in self.data: 1679 self.data.append(elem) 1680 def __contains__(self, elem): 1681 return elem in self.data 1682 def __iter__(self): 1683 return iter(self.data) 1684 def __len__(self): 1685 return len(self.data) 1686 def __repr__(self): 1687 return 'Set({!r})'.format(self.data) 1688 1689 r1 = set('abc') 1690 r2 = set('bcd') 1691 r3 = set('abcde') 1692 f1 = ListSet('abc') 1693 f2 = ListSet('bcd') 1694 f3 = ListSet('abcde') 1695 l1 = list('abccba') 1696 l2 = list('bcddcb') 1697 l3 = list('abcdeedcba') 1698 1699 target = r1 & r2 1700 self.assertSameSet(f1 & f2, target) 1701 self.assertSameSet(f1 & r2, target) 1702 self.assertSameSet(r2 & f1, target) 1703 self.assertSameSet(f1 & l2, target) 1704 1705 target = r1 | r2 1706 self.assertSameSet(f1 | f2, target) 1707 self.assertSameSet(f1 | r2, target) 1708 self.assertSameSet(r2 | f1, target) 1709 self.assertSameSet(f1 | l2, target) 1710 1711 fwd_target = r1 - r2 1712 rev_target = r2 - r1 1713 self.assertSameSet(f1 - f2, fwd_target) 1714 self.assertSameSet(f2 - f1, rev_target) 1715 self.assertSameSet(f1 - r2, fwd_target) 1716 self.assertSameSet(f2 - r1, rev_target) 1717 self.assertSameSet(r1 - f2, fwd_target) 1718 self.assertSameSet(r2 - f1, rev_target) 1719 self.assertSameSet(f1 - l2, fwd_target) 1720 self.assertSameSet(f2 - l1, rev_target) 1721 1722 target = r1 ^ r2 1723 self.assertSameSet(f1 ^ f2, target) 1724 self.assertSameSet(f1 ^ r2, target) 1725 self.assertSameSet(r2 ^ f1, target) 1726 self.assertSameSet(f1 ^ l2, target) 1727 1728 # Don't change the following to use assertLess or other 1729 # "more specific" unittest assertions. The current 1730 # assertTrue/assertFalse style makes the pattern of test 1731 # case combinations clear and allows us to know for sure 1732 # the exact operator being invoked. 1733 1734 # proper subset 1735 self.assertTrue(f1 < f3) 1736 self.assertFalse(f1 < f1) 1737 self.assertFalse(f1 < f2) 1738 self.assertTrue(r1 < f3) 1739 self.assertFalse(r1 < f1) 1740 self.assertFalse(r1 < f2) 1741 self.assertTrue(r1 < r3) 1742 self.assertFalse(r1 < r1) 1743 self.assertFalse(r1 < r2) 1744 with self.assertRaises(TypeError): 1745 f1 < l3 1746 with self.assertRaises(TypeError): 1747 f1 < l1 1748 with self.assertRaises(TypeError): 1749 f1 < l2 1750 1751 # any subset 1752 self.assertTrue(f1 <= f3) 1753 self.assertTrue(f1 <= f1) 1754 self.assertFalse(f1 <= f2) 1755 self.assertTrue(r1 <= f3) 1756 self.assertTrue(r1 <= f1) 1757 self.assertFalse(r1 <= f2) 1758 self.assertTrue(r1 <= r3) 1759 self.assertTrue(r1 <= r1) 1760 self.assertFalse(r1 <= r2) 1761 with self.assertRaises(TypeError): 1762 f1 <= l3 1763 with self.assertRaises(TypeError): 1764 f1 <= l1 1765 with self.assertRaises(TypeError): 1766 f1 <= l2 1767 1768 # proper superset 1769 self.assertTrue(f3 > f1) 1770 self.assertFalse(f1 > f1) 1771 self.assertFalse(f2 > f1) 1772 self.assertTrue(r3 > r1) 1773 self.assertFalse(f1 > r1) 1774 self.assertFalse(f2 > r1) 1775 self.assertTrue(r3 > r1) 1776 self.assertFalse(r1 > r1) 1777 self.assertFalse(r2 > r1) 1778 with self.assertRaises(TypeError): 1779 f1 > l3 1780 with self.assertRaises(TypeError): 1781 f1 > l1 1782 with self.assertRaises(TypeError): 1783 f1 > l2 1784 1785 # any superset 1786 self.assertTrue(f3 >= f1) 1787 self.assertTrue(f1 >= f1) 1788 self.assertFalse(f2 >= f1) 1789 self.assertTrue(r3 >= r1) 1790 self.assertTrue(f1 >= r1) 1791 self.assertFalse(f2 >= r1) 1792 self.assertTrue(r3 >= r1) 1793 self.assertTrue(r1 >= r1) 1794 self.assertFalse(r2 >= r1) 1795 with self.assertRaises(TypeError): 1796 f1 >= l3 1797 with self.assertRaises(TypeError): 1798 f1 >=l1 1799 with self.assertRaises(TypeError): 1800 f1 >= l2 1801 1802 # equality 1803 self.assertTrue(f1 == f1) 1804 self.assertTrue(r1 == f1) 1805 self.assertTrue(f1 == r1) 1806 self.assertFalse(f1 == f3) 1807 self.assertFalse(r1 == f3) 1808 self.assertFalse(f1 == r3) 1809 self.assertFalse(f1 == l3) 1810 self.assertFalse(f1 == l1) 1811 self.assertFalse(f1 == l2) 1812 1813 # inequality 1814 self.assertFalse(f1 != f1) 1815 self.assertFalse(r1 != f1) 1816 self.assertFalse(f1 != r1) 1817 self.assertTrue(f1 != f3) 1818 self.assertTrue(r1 != f3) 1819 self.assertTrue(f1 != r3) 1820 self.assertTrue(f1 != l3) 1821 self.assertTrue(f1 != l1) 1822 self.assertTrue(f1 != l2) 1823 1824 def test_Set_hash_matches_frozenset(self): 1825 sets = [ 1826 {}, {1}, {None}, {-1}, {0.0}, {"abc"}, {1, 2, 3}, 1827 {10**100, 10**101}, {"a", "b", "ab", ""}, {False, True}, 1828 {object(), object(), object()}, {float("nan")}, {frozenset()}, 1829 {*range(1000)}, {*range(1000)} - {100, 200, 300}, 1830 {*range(sys.maxsize - 10, sys.maxsize + 10)}, 1831 ] 1832 for s in sets: 1833 fs = frozenset(s) 1834 self.assertEqual(hash(fs), Set._hash(fs), msg=s) 1835 1836 def test_Mapping(self): 1837 for sample in [dict]: 1838 self.assertIsInstance(sample(), Mapping) 1839 self.assertTrue(issubclass(sample, Mapping)) 1840 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', 1841 '__getitem__') 1842 class MyMapping(Mapping): 1843 def __len__(self): 1844 return 0 1845 def __getitem__(self, i): 1846 raise IndexError 1847 def __iter__(self): 1848 return iter(()) 1849 self.validate_comparison(MyMapping()) 1850 self.assertRaises(TypeError, reversed, MyMapping()) 1851 1852 def test_MutableMapping(self): 1853 for sample in [dict]: 1854 self.assertIsInstance(sample(), MutableMapping) 1855 self.assertTrue(issubclass(sample, MutableMapping)) 1856 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', 1857 '__getitem__', '__setitem__', '__delitem__') 1858 1859 def test_MutableMapping_subclass(self): 1860 # Test issue 9214 1861 mymap = UserDict() 1862 mymap['red'] = 5 1863 self.assertIsInstance(mymap.keys(), Set) 1864 self.assertIsInstance(mymap.keys(), KeysView) 1865 self.assertIsInstance(mymap.values(), Collection) 1866 self.assertIsInstance(mymap.values(), ValuesView) 1867 self.assertIsInstance(mymap.items(), Set) 1868 self.assertIsInstance(mymap.items(), ItemsView) 1869 1870 mymap = UserDict() 1871 mymap['red'] = 5 1872 z = mymap.keys() | {'orange'} 1873 self.assertIsInstance(z, set) 1874 list(z) 1875 mymap['blue'] = 7 # Shouldn't affect 'z' 1876 self.assertEqual(sorted(z), ['orange', 'red']) 1877 1878 mymap = UserDict() 1879 mymap['red'] = 5 1880 z = mymap.items() | {('orange', 3)} 1881 self.assertIsInstance(z, set) 1882 list(z) 1883 mymap['blue'] = 7 # Shouldn't affect 'z' 1884 self.assertEqual(z, {('orange', 3), ('red', 5)}) 1885 1886 def test_Sequence(self): 1887 for sample in [tuple, list, bytes, str]: 1888 self.assertIsInstance(sample(), Sequence) 1889 self.assertTrue(issubclass(sample, Sequence)) 1890 self.assertIsInstance(range(10), Sequence) 1891 self.assertTrue(issubclass(range, Sequence)) 1892 self.assertIsInstance(memoryview(b""), Sequence) 1893 self.assertTrue(issubclass(memoryview, Sequence)) 1894 self.assertTrue(issubclass(str, Sequence)) 1895 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', 1896 '__getitem__') 1897 1898 def test_Sequence_mixins(self): 1899 class SequenceSubclass(Sequence): 1900 def __init__(self, seq=()): 1901 self.seq = seq 1902 1903 def __getitem__(self, index): 1904 return self.seq[index] 1905 1906 def __len__(self): 1907 return len(self.seq) 1908 1909 # Compare Sequence.index() behavior to (list|str).index() behavior 1910 def assert_index_same(seq1, seq2, index_args): 1911 try: 1912 expected = seq1.index(*index_args) 1913 except ValueError: 1914 with self.assertRaises(ValueError): 1915 seq2.index(*index_args) 1916 else: 1917 actual = seq2.index(*index_args) 1918 self.assertEqual( 1919 actual, expected, '%r.index%s' % (seq1, index_args)) 1920 1921 for ty in list, str: 1922 nativeseq = ty('abracadabra') 1923 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3)) 1924 seqseq = SequenceSubclass(nativeseq) 1925 for letter in set(nativeseq) | {'z'}: 1926 assert_index_same(nativeseq, seqseq, (letter,)) 1927 for start in range(-3, len(nativeseq) + 3): 1928 assert_index_same(nativeseq, seqseq, (letter, start)) 1929 for stop in range(-3, len(nativeseq) + 3): 1930 assert_index_same( 1931 nativeseq, seqseq, (letter, start, stop)) 1932 1933 def test_ByteString(self): 1934 for sample in [bytes, bytearray]: 1935 self.assertIsInstance(sample(), ByteString) 1936 self.assertTrue(issubclass(sample, ByteString)) 1937 for sample in [str, list, tuple]: 1938 self.assertNotIsInstance(sample(), ByteString) 1939 self.assertFalse(issubclass(sample, ByteString)) 1940 self.assertNotIsInstance(memoryview(b""), ByteString) 1941 self.assertFalse(issubclass(memoryview, ByteString)) 1942 self.validate_abstract_methods(ByteString, '__getitem__', '__len__') 1943 1944 def test_MutableSequence(self): 1945 for sample in [tuple, str, bytes]: 1946 self.assertNotIsInstance(sample(), MutableSequence) 1947 self.assertFalse(issubclass(sample, MutableSequence)) 1948 for sample in [list, bytearray, deque]: 1949 self.assertIsInstance(sample(), MutableSequence) 1950 self.assertTrue(issubclass(sample, MutableSequence)) 1951 self.assertFalse(issubclass(str, MutableSequence)) 1952 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', 1953 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') 1954 1955 def test_MutableSequence_mixins(self): 1956 # Test the mixins of MutableSequence by creating a minimal concrete 1957 # class inherited from it. 1958 class MutableSequenceSubclass(MutableSequence): 1959 def __init__(self): 1960 self.lst = [] 1961 1962 def __setitem__(self, index, value): 1963 self.lst[index] = value 1964 1965 def __getitem__(self, index): 1966 return self.lst[index] 1967 1968 def __len__(self): 1969 return len(self.lst) 1970 1971 def __delitem__(self, index): 1972 del self.lst[index] 1973 1974 def insert(self, index, value): 1975 self.lst.insert(index, value) 1976 1977 mss = MutableSequenceSubclass() 1978 mss.append(0) 1979 mss.extend((1, 2, 3, 4)) 1980 self.assertEqual(len(mss), 5) 1981 self.assertEqual(mss[3], 3) 1982 mss.reverse() 1983 self.assertEqual(mss[3], 1) 1984 mss.pop() 1985 self.assertEqual(len(mss), 4) 1986 mss.remove(3) 1987 self.assertEqual(len(mss), 3) 1988 mss += (10, 20, 30) 1989 self.assertEqual(len(mss), 6) 1990 self.assertEqual(mss[-1], 30) 1991 mss.clear() 1992 self.assertEqual(len(mss), 0) 1993 1994 # issue 34427 1995 # extending self should not cause infinite loop 1996 items = 'ABCD' 1997 mss2 = MutableSequenceSubclass() 1998 mss2.extend(items + items) 1999 mss.clear() 2000 mss.extend(items) 2001 mss.extend(mss) 2002 self.assertEqual(len(mss), len(mss2)) 2003 self.assertEqual(list(mss), list(mss2)) 2004 2005 def test_illegal_patma_flags(self): 2006 with self.assertRaises(TypeError): 2007 class Both(Collection): 2008 __abc_tpflags__ = (Sequence.__flags__ | Mapping.__flags__) 2009 2010 2011 2012################################################################################ 2013### Counter 2014################################################################################ 2015 2016class CounterSubclassWithSetItem(Counter): 2017 # Test a counter subclass that overrides __setitem__ 2018 def __init__(self, *args, **kwds): 2019 self.called = False 2020 Counter.__init__(self, *args, **kwds) 2021 def __setitem__(self, key, value): 2022 self.called = True 2023 Counter.__setitem__(self, key, value) 2024 2025class CounterSubclassWithGet(Counter): 2026 # Test a counter subclass that overrides get() 2027 def __init__(self, *args, **kwds): 2028 self.called = False 2029 Counter.__init__(self, *args, **kwds) 2030 def get(self, key, default): 2031 self.called = True 2032 return Counter.get(self, key, default) 2033 2034class TestCounter(unittest.TestCase): 2035 2036 def test_basics(self): 2037 c = Counter('abcaba') 2038 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) 2039 self.assertEqual(c, Counter(a=3, b=2, c=1)) 2040 self.assertIsInstance(c, dict) 2041 self.assertIsInstance(c, Mapping) 2042 self.assertTrue(issubclass(Counter, dict)) 2043 self.assertTrue(issubclass(Counter, Mapping)) 2044 self.assertEqual(len(c), 3) 2045 self.assertEqual(sum(c.values()), 6) 2046 self.assertEqual(list(c.values()), [3, 2, 1]) 2047 self.assertEqual(list(c.keys()), ['a', 'b', 'c']) 2048 self.assertEqual(list(c), ['a', 'b', 'c']) 2049 self.assertEqual(list(c.items()), 2050 [('a', 3), ('b', 2), ('c', 1)]) 2051 self.assertEqual(c['b'], 2) 2052 self.assertEqual(c['z'], 0) 2053 self.assertEqual(c.__contains__('c'), True) 2054 self.assertEqual(c.__contains__('z'), False) 2055 self.assertEqual(c.get('b', 10), 2) 2056 self.assertEqual(c.get('z', 10), 10) 2057 self.assertEqual(c, dict(a=3, b=2, c=1)) 2058 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") 2059 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) 2060 for i in range(5): 2061 self.assertEqual(c.most_common(i), 2062 [('a', 3), ('b', 2), ('c', 1)][:i]) 2063 self.assertEqual(''.join(c.elements()), 'aaabbc') 2064 c['a'] += 1 # increment an existing value 2065 c['b'] -= 2 # sub existing value to zero 2066 del c['c'] # remove an entry 2067 del c['c'] # make sure that del doesn't raise KeyError 2068 c['d'] -= 2 # sub from a missing value 2069 c['e'] = -5 # directly assign a missing value 2070 c['f'] += 4 # add to a missing value 2071 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) 2072 self.assertEqual(''.join(c.elements()), 'aaaaffff') 2073 self.assertEqual(c.pop('f'), 4) 2074 self.assertNotIn('f', c) 2075 for i in range(3): 2076 elem, cnt = c.popitem() 2077 self.assertNotIn(elem, c) 2078 c.clear() 2079 self.assertEqual(c, {}) 2080 self.assertEqual(repr(c), 'Counter()') 2081 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') 2082 self.assertRaises(TypeError, hash, c) 2083 c.update(dict(a=5, b=3)) 2084 c.update(c=1) 2085 c.update(Counter('a' * 50 + 'b' * 30)) 2086 c.update() # test case with no args 2087 c.__init__('a' * 500 + 'b' * 300) 2088 c.__init__('cdc') 2089 c.__init__() 2090 self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) 2091 self.assertEqual(c.setdefault('d', 5), 1) 2092 self.assertEqual(c['d'], 1) 2093 self.assertEqual(c.setdefault('e', 5), 5) 2094 self.assertEqual(c['e'], 5) 2095 2096 def test_init(self): 2097 self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) 2098 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) 2099 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) 2100 self.assertRaises(TypeError, Counter, 42) 2101 self.assertRaises(TypeError, Counter, (), ()) 2102 self.assertRaises(TypeError, Counter.__init__) 2103 2104 def test_total(self): 2105 c = Counter(a=10, b=5, c=0) 2106 self.assertEqual(c.total(), 15) 2107 2108 def test_order_preservation(self): 2109 # Input order dictates items() order 2110 self.assertEqual(list(Counter('abracadabra').items()), 2111 [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]) 2112 # letters with same count: ^----------^ ^---------^ 2113 2114 # Verify retention of order even when all counts are equal 2115 self.assertEqual(list(Counter('xyzpdqqdpzyx').items()), 2116 [('x', 2), ('y', 2), ('z', 2), ('p', 2), ('d', 2), ('q', 2)]) 2117 2118 # Input order dictates elements() order 2119 self.assertEqual(list(Counter('abracadabra simsalabim').elements()), 2120 ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b','r', 2121 'r', 'c', 'd', ' ', 's', 's', 'i', 'i', 'm', 'm', 'l']) 2122 2123 # Math operations order first by the order encountered in the left 2124 # operand and then by the order encountered in the right operand. 2125 ps = 'aaabbcdddeefggghhijjjkkl' 2126 qs = 'abbcccdeefffhkkllllmmnno' 2127 order = {letter: i for i, letter in enumerate(dict.fromkeys(ps + qs))} 2128 def correctly_ordered(seq): 2129 'Return true if the letters occur in the expected order' 2130 positions = [order[letter] for letter in seq] 2131 return positions == sorted(positions) 2132 2133 p, q = Counter(ps), Counter(qs) 2134 self.assertTrue(correctly_ordered(+p)) 2135 self.assertTrue(correctly_ordered(-p)) 2136 self.assertTrue(correctly_ordered(p + q)) 2137 self.assertTrue(correctly_ordered(p - q)) 2138 self.assertTrue(correctly_ordered(p | q)) 2139 self.assertTrue(correctly_ordered(p & q)) 2140 2141 p, q = Counter(ps), Counter(qs) 2142 p += q 2143 self.assertTrue(correctly_ordered(p)) 2144 2145 p, q = Counter(ps), Counter(qs) 2146 p -= q 2147 self.assertTrue(correctly_ordered(p)) 2148 2149 p, q = Counter(ps), Counter(qs) 2150 p |= q 2151 self.assertTrue(correctly_ordered(p)) 2152 2153 p, q = Counter(ps), Counter(qs) 2154 p &= q 2155 self.assertTrue(correctly_ordered(p)) 2156 2157 p, q = Counter(ps), Counter(qs) 2158 p.update(q) 2159 self.assertTrue(correctly_ordered(p)) 2160 2161 p, q = Counter(ps), Counter(qs) 2162 p.subtract(q) 2163 self.assertTrue(correctly_ordered(p)) 2164 2165 def test_update(self): 2166 c = Counter() 2167 c.update(self=42) 2168 self.assertEqual(list(c.items()), [('self', 42)]) 2169 c = Counter() 2170 c.update(iterable=42) 2171 self.assertEqual(list(c.items()), [('iterable', 42)]) 2172 c = Counter() 2173 c.update(iterable=None) 2174 self.assertEqual(list(c.items()), [('iterable', None)]) 2175 self.assertRaises(TypeError, Counter().update, 42) 2176 self.assertRaises(TypeError, Counter().update, {}, {}) 2177 self.assertRaises(TypeError, Counter.update) 2178 2179 def test_copying(self): 2180 # Check that counters are copyable, deepcopyable, picklable, and 2181 #have a repr/eval round-trip 2182 words = Counter('which witch had which witches wrist watch'.split()) 2183 def check(dup): 2184 msg = "\ncopy: %s\nwords: %s" % (dup, words) 2185 self.assertIsNot(dup, words, msg) 2186 self.assertEqual(dup, words) 2187 check(words.copy()) 2188 check(copy.copy(words)) 2189 check(copy.deepcopy(words)) 2190 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2191 with self.subTest(proto=proto): 2192 check(pickle.loads(pickle.dumps(words, proto))) 2193 check(eval(repr(words))) 2194 update_test = Counter() 2195 update_test.update(words) 2196 check(update_test) 2197 check(Counter(words)) 2198 2199 def test_copy_subclass(self): 2200 class MyCounter(Counter): 2201 pass 2202 c = MyCounter('slartibartfast') 2203 d = c.copy() 2204 self.assertEqual(d, c) 2205 self.assertEqual(len(d), len(c)) 2206 self.assertEqual(type(d), type(c)) 2207 2208 def test_conversions(self): 2209 # Convert to: set, list, dict 2210 s = 'she sells sea shells by the sea shore' 2211 self.assertEqual(sorted(Counter(s).elements()), sorted(s)) 2212 self.assertEqual(sorted(Counter(s)), sorted(set(s))) 2213 self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) 2214 self.assertEqual(set(Counter(s)), set(s)) 2215 2216 def test_invariant_for_the_in_operator(self): 2217 c = Counter(a=10, b=-2, c=0) 2218 for elem in c: 2219 self.assertTrue(elem in c) 2220 self.assertIn(elem, c) 2221 2222 def test_multiset_operations(self): 2223 # Verify that adding a zero counter will strip zeros and negatives 2224 c = Counter(a=10, b=-2, c=0) + Counter() 2225 self.assertEqual(dict(c), dict(a=10)) 2226 2227 elements = 'abcd' 2228 for i in range(1000): 2229 # test random pairs of multisets 2230 p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2231 p.update(e=1, f=-1, g=0) 2232 q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2233 q.update(h=1, i=-1, j=0) 2234 for counterop, numberop in [ 2235 (Counter.__add__, lambda x, y: max(0, x+y)), 2236 (Counter.__sub__, lambda x, y: max(0, x-y)), 2237 (Counter.__or__, lambda x, y: max(0,x,y)), 2238 (Counter.__and__, lambda x, y: max(0, min(x,y))), 2239 ]: 2240 result = counterop(p, q) 2241 for x in elements: 2242 self.assertEqual(numberop(p[x], q[x]), result[x], 2243 (counterop, x, p, q)) 2244 # verify that results exclude non-positive counts 2245 self.assertTrue(x>0 for x in result.values()) 2246 2247 elements = 'abcdef' 2248 for i in range(100): 2249 # verify that random multisets with no repeats are exactly like sets 2250 p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) 2251 q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) 2252 for counterop, setop in [ 2253 (Counter.__sub__, set.__sub__), 2254 (Counter.__or__, set.__or__), 2255 (Counter.__and__, set.__and__), 2256 ]: 2257 counter_result = counterop(p, q) 2258 set_result = setop(set(p.elements()), set(q.elements())) 2259 self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) 2260 2261 def test_inplace_operations(self): 2262 elements = 'abcd' 2263 for i in range(1000): 2264 # test random pairs of multisets 2265 p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2266 p.update(e=1, f=-1, g=0) 2267 q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2268 q.update(h=1, i=-1, j=0) 2269 for inplace_op, regular_op in [ 2270 (Counter.__iadd__, Counter.__add__), 2271 (Counter.__isub__, Counter.__sub__), 2272 (Counter.__ior__, Counter.__or__), 2273 (Counter.__iand__, Counter.__and__), 2274 ]: 2275 c = p.copy() 2276 c_id = id(c) 2277 regular_result = regular_op(c, q) 2278 inplace_result = inplace_op(c, q) 2279 self.assertEqual(inplace_result, regular_result) 2280 self.assertEqual(id(inplace_result), c_id) 2281 2282 def test_subtract(self): 2283 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 2284 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) 2285 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) 2286 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 2287 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) 2288 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) 2289 c = Counter('aaabbcd') 2290 c.subtract('aaaabbcce') 2291 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) 2292 2293 c = Counter() 2294 c.subtract(self=42) 2295 self.assertEqual(list(c.items()), [('self', -42)]) 2296 c = Counter() 2297 c.subtract(iterable=42) 2298 self.assertEqual(list(c.items()), [('iterable', -42)]) 2299 self.assertRaises(TypeError, Counter().subtract, 42) 2300 self.assertRaises(TypeError, Counter().subtract, {}, {}) 2301 self.assertRaises(TypeError, Counter.subtract) 2302 2303 def test_unary(self): 2304 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 2305 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) 2306 self.assertEqual(dict(-c), dict(a=5)) 2307 2308 def test_repr_nonsortable(self): 2309 c = Counter(a=2, b=None) 2310 r = repr(c) 2311 self.assertIn("'a': 2", r) 2312 self.assertIn("'b': None", r) 2313 2314 def test_helper_function(self): 2315 # two paths, one for real dicts and one for other mappings 2316 elems = list('abracadabra') 2317 2318 d = dict() 2319 _count_elements(d, elems) 2320 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) 2321 2322 m = OrderedDict() 2323 _count_elements(m, elems) 2324 self.assertEqual(m, 2325 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) 2326 2327 # test fidelity to the pure python version 2328 c = CounterSubclassWithSetItem('abracadabra') 2329 self.assertTrue(c.called) 2330 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) 2331 c = CounterSubclassWithGet('abracadabra') 2332 self.assertTrue(c.called) 2333 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) 2334 2335 def test_multiset_operations_equivalent_to_set_operations(self): 2336 # When the multiplicities are all zero or one, multiset operations 2337 # are guaranteed to be equivalent to the corresponding operations 2338 # for regular sets. 2339 s = list(product(('a', 'b', 'c'), range(2))) 2340 powerset = chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) 2341 counters = [Counter(dict(groups)) for groups in powerset] 2342 for cp, cq in product(counters, repeat=2): 2343 sp = set(cp.elements()) 2344 sq = set(cq.elements()) 2345 self.assertEqual(set(cp + cq), sp | sq) 2346 self.assertEqual(set(cp - cq), sp - sq) 2347 self.assertEqual(set(cp | cq), sp | sq) 2348 self.assertEqual(set(cp & cq), sp & sq) 2349 self.assertEqual(cp == cq, sp == sq) 2350 self.assertEqual(cp != cq, sp != sq) 2351 self.assertEqual(cp <= cq, sp <= sq) 2352 self.assertEqual(cp >= cq, sp >= sq) 2353 self.assertEqual(cp < cq, sp < sq) 2354 self.assertEqual(cp > cq, sp > sq) 2355 2356 def test_eq(self): 2357 self.assertEqual(Counter(a=3, b=2, c=0), Counter('ababa')) 2358 self.assertNotEqual(Counter(a=3, b=2), Counter('babab')) 2359 2360 def test_le(self): 2361 self.assertTrue(Counter(a=3, b=2, c=0) <= Counter('ababa')) 2362 self.assertFalse(Counter(a=3, b=2) <= Counter('babab')) 2363 2364 def test_lt(self): 2365 self.assertTrue(Counter(a=3, b=1, c=0) < Counter('ababa')) 2366 self.assertFalse(Counter(a=3, b=2, c=0) < Counter('ababa')) 2367 2368 def test_ge(self): 2369 self.assertTrue(Counter(a=2, b=1, c=0) >= Counter('aab')) 2370 self.assertFalse(Counter(a=3, b=2, c=0) >= Counter('aabd')) 2371 2372 def test_gt(self): 2373 self.assertTrue(Counter(a=3, b=2, c=0) > Counter('aab')) 2374 self.assertFalse(Counter(a=2, b=1, c=0) > Counter('aab')) 2375 2376 2377def load_tests(loader, tests, pattern): 2378 tests.addTest(doctest.DocTestSuite(collections)) 2379 return tests 2380 2381 2382if __name__ == "__main__": 2383 unittest.main() 2384