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 class NewPoint(tuple): 681 x = pickle.loads(pickle.dumps(Point.x)) 682 y = pickle.loads(pickle.dumps(Point.y)) 683 684 np = NewPoint([1, 2]) 685 686 self.assertEqual(np.x, 1) 687 self.assertEqual(np.y, 2) 688 689 def test_new_builtins_issue_43102(self): 690 obj = namedtuple('C', ()) 691 new_func = obj.__new__ 692 self.assertEqual(new_func.__globals__['__builtins__'], {}) 693 self.assertEqual(new_func.__builtins__, {}) 694 695 def test_match_args(self): 696 Point = namedtuple('Point', 'x y') 697 self.assertEqual(Point.__match_args__, ('x', 'y')) 698 699 700################################################################################ 701### Abstract Base Classes 702################################################################################ 703 704class ABCTestCase(unittest.TestCase): 705 706 def validate_abstract_methods(self, abc, *names): 707 methodstubs = dict.fromkeys(names, lambda s, *args: 0) 708 709 # everything should work will all required methods are present 710 C = type('C', (abc,), methodstubs) 711 C() 712 713 # instantiation should fail if a required method is missing 714 for name in names: 715 stubs = methodstubs.copy() 716 del stubs[name] 717 C = type('C', (abc,), stubs) 718 self.assertRaises(TypeError, C, name) 719 720 def validate_isinstance(self, abc, name): 721 stub = lambda s, *args: 0 722 723 C = type('C', (object,), {'__hash__': None}) 724 setattr(C, name, stub) 725 self.assertIsInstance(C(), abc) 726 self.assertTrue(issubclass(C, abc)) 727 728 C = type('C', (object,), {'__hash__': None}) 729 self.assertNotIsInstance(C(), abc) 730 self.assertFalse(issubclass(C, abc)) 731 732 def validate_comparison(self, instance): 733 ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] 734 operators = {} 735 for op in ops: 736 name = '__' + op + '__' 737 operators[name] = getattr(operator, name) 738 739 class Other: 740 def __init__(self): 741 self.right_side = False 742 def __eq__(self, other): 743 self.right_side = True 744 return True 745 __lt__ = __eq__ 746 __gt__ = __eq__ 747 __le__ = __eq__ 748 __ge__ = __eq__ 749 __ne__ = __eq__ 750 __ror__ = __eq__ 751 __rand__ = __eq__ 752 __rxor__ = __eq__ 753 __rsub__ = __eq__ 754 755 for name, op in operators.items(): 756 if not hasattr(instance, name): 757 continue 758 other = Other() 759 op(instance, other) 760 self.assertTrue(other.right_side,'Right side not called for %s.%s' 761 % (type(instance), name)) 762 763def _test_gen(): 764 yield 765 766class TestOneTrickPonyABCs(ABCTestCase): 767 768 def test_Awaitable(self): 769 def gen(): 770 yield 771 772 @types.coroutine 773 def coro(): 774 yield 775 776 async def new_coro(): 777 pass 778 779 class Bar: 780 def __await__(self): 781 yield 782 783 class MinimalCoro(Coroutine): 784 def send(self, value): 785 return value 786 def throw(self, typ, val=None, tb=None): 787 super().throw(typ, val, tb) 788 def __await__(self): 789 yield 790 791 non_samples = [None, int(), gen(), object()] 792 for x in non_samples: 793 self.assertNotIsInstance(x, Awaitable) 794 self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) 795 796 samples = [Bar(), MinimalCoro()] 797 for x in samples: 798 self.assertIsInstance(x, Awaitable) 799 self.assertTrue(issubclass(type(x), Awaitable)) 800 801 c = coro() 802 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE 803 # flag don't have '__await__' method, hence can't be instances 804 # of Awaitable. Use inspect.isawaitable to detect them. 805 self.assertNotIsInstance(c, Awaitable) 806 807 c = new_coro() 808 self.assertIsInstance(c, Awaitable) 809 c.close() # avoid RuntimeWarning that coro() was not awaited 810 811 class CoroLike: pass 812 Coroutine.register(CoroLike) 813 self.assertTrue(isinstance(CoroLike(), Awaitable)) 814 self.assertTrue(issubclass(CoroLike, Awaitable)) 815 CoroLike = None 816 support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache 817 818 def test_Coroutine(self): 819 def gen(): 820 yield 821 822 @types.coroutine 823 def coro(): 824 yield 825 826 async def new_coro(): 827 pass 828 829 class Bar: 830 def __await__(self): 831 yield 832 833 class MinimalCoro(Coroutine): 834 def send(self, value): 835 return value 836 def throw(self, typ, val=None, tb=None): 837 super().throw(typ, val, tb) 838 def __await__(self): 839 yield 840 841 non_samples = [None, int(), gen(), object(), Bar()] 842 for x in non_samples: 843 self.assertNotIsInstance(x, Coroutine) 844 self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) 845 846 samples = [MinimalCoro()] 847 for x in samples: 848 self.assertIsInstance(x, Awaitable) 849 self.assertTrue(issubclass(type(x), Awaitable)) 850 851 c = coro() 852 # Iterable coroutines (generators with CO_ITERABLE_COROUTINE 853 # flag don't have '__await__' method, hence can't be instances 854 # of Coroutine. Use inspect.isawaitable to detect them. 855 self.assertNotIsInstance(c, Coroutine) 856 857 c = new_coro() 858 self.assertIsInstance(c, Coroutine) 859 c.close() # avoid RuntimeWarning that coro() was not awaited 860 861 class CoroLike: 862 def send(self, value): 863 pass 864 def throw(self, typ, val=None, tb=None): 865 pass 866 def close(self): 867 pass 868 def __await__(self): 869 pass 870 self.assertTrue(isinstance(CoroLike(), Coroutine)) 871 self.assertTrue(issubclass(CoroLike, Coroutine)) 872 873 class CoroLike: 874 def send(self, value): 875 pass 876 def close(self): 877 pass 878 def __await__(self): 879 pass 880 self.assertFalse(isinstance(CoroLike(), Coroutine)) 881 self.assertFalse(issubclass(CoroLike, Coroutine)) 882 883 def test_Hashable(self): 884 # Check some non-hashables 885 non_samples = [bytearray(), list(), set(), dict()] 886 for x in non_samples: 887 self.assertNotIsInstance(x, Hashable) 888 self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) 889 # Check some hashables 890 samples = [None, 891 int(), float(), complex(), 892 str(), 893 tuple(), frozenset(), 894 int, list, object, type, bytes() 895 ] 896 for x in samples: 897 self.assertIsInstance(x, Hashable) 898 self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) 899 self.assertRaises(TypeError, Hashable) 900 # Check direct subclassing 901 class H(Hashable): 902 def __hash__(self): 903 return super().__hash__() 904 self.assertEqual(hash(H()), 0) 905 self.assertFalse(issubclass(int, H)) 906 self.validate_abstract_methods(Hashable, '__hash__') 907 self.validate_isinstance(Hashable, '__hash__') 908 909 def test_AsyncIterable(self): 910 class AI: 911 def __aiter__(self): 912 return self 913 self.assertTrue(isinstance(AI(), AsyncIterable)) 914 self.assertTrue(issubclass(AI, AsyncIterable)) 915 # Check some non-iterables 916 non_samples = [None, object, []] 917 for x in non_samples: 918 self.assertNotIsInstance(x, AsyncIterable) 919 self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) 920 self.validate_abstract_methods(AsyncIterable, '__aiter__') 921 self.validate_isinstance(AsyncIterable, '__aiter__') 922 923 def test_AsyncIterator(self): 924 class AI: 925 def __aiter__(self): 926 return self 927 async def __anext__(self): 928 raise StopAsyncIteration 929 self.assertTrue(isinstance(AI(), AsyncIterator)) 930 self.assertTrue(issubclass(AI, AsyncIterator)) 931 non_samples = [None, object, []] 932 # Check some non-iterables 933 for x in non_samples: 934 self.assertNotIsInstance(x, AsyncIterator) 935 self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) 936 # Similarly to regular iterators (see issue 10565) 937 class AnextOnly: 938 async def __anext__(self): 939 raise StopAsyncIteration 940 self.assertNotIsInstance(AnextOnly(), AsyncIterator) 941 self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') 942 943 def test_Iterable(self): 944 # Check some non-iterables 945 non_samples = [None, 42, 3.14, 1j] 946 for x in non_samples: 947 self.assertNotIsInstance(x, Iterable) 948 self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) 949 # Check some iterables 950 samples = [bytes(), str(), 951 tuple(), list(), set(), frozenset(), dict(), 952 dict().keys(), dict().items(), dict().values(), 953 _test_gen(), 954 (x for x in []), 955 ] 956 for x in samples: 957 self.assertIsInstance(x, Iterable) 958 self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) 959 # Check direct subclassing 960 class I(Iterable): 961 def __iter__(self): 962 return super().__iter__() 963 self.assertEqual(list(I()), []) 964 self.assertFalse(issubclass(str, I)) 965 self.validate_abstract_methods(Iterable, '__iter__') 966 self.validate_isinstance(Iterable, '__iter__') 967 # Check None blocking 968 class It: 969 def __iter__(self): return iter([]) 970 class ItBlocked(It): 971 __iter__ = None 972 self.assertTrue(issubclass(It, Iterable)) 973 self.assertTrue(isinstance(It(), Iterable)) 974 self.assertFalse(issubclass(ItBlocked, Iterable)) 975 self.assertFalse(isinstance(ItBlocked(), Iterable)) 976 977 def test_Reversible(self): 978 # Check some non-reversibles 979 non_samples = [None, 42, 3.14, 1j, set(), frozenset()] 980 for x in non_samples: 981 self.assertNotIsInstance(x, Reversible) 982 self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) 983 # Check some non-reversible iterables 984 non_reversibles = [_test_gen(), (x for x in []), iter([]), reversed([])] 985 for x in non_reversibles: 986 self.assertNotIsInstance(x, Reversible) 987 self.assertFalse(issubclass(type(x), Reversible), repr(type(x))) 988 # Check some reversible iterables 989 samples = [bytes(), str(), tuple(), list(), OrderedDict(), 990 OrderedDict().keys(), OrderedDict().items(), 991 OrderedDict().values(), Counter(), Counter().keys(), 992 Counter().items(), Counter().values(), dict(), 993 dict().keys(), dict().items(), dict().values()] 994 for x in samples: 995 self.assertIsInstance(x, Reversible) 996 self.assertTrue(issubclass(type(x), Reversible), repr(type(x))) 997 # Check also Mapping, MutableMapping, and Sequence 998 self.assertTrue(issubclass(Sequence, Reversible), repr(Sequence)) 999 self.assertFalse(issubclass(Mapping, Reversible), repr(Mapping)) 1000 self.assertFalse(issubclass(MutableMapping, Reversible), repr(MutableMapping)) 1001 # Check direct subclassing 1002 class R(Reversible): 1003 def __iter__(self): 1004 return iter(list()) 1005 def __reversed__(self): 1006 return iter(list()) 1007 self.assertEqual(list(reversed(R())), []) 1008 self.assertFalse(issubclass(float, R)) 1009 self.validate_abstract_methods(Reversible, '__reversed__', '__iter__') 1010 # Check reversible non-iterable (which is not Reversible) 1011 class RevNoIter: 1012 def __reversed__(self): return reversed([]) 1013 class RevPlusIter(RevNoIter): 1014 def __iter__(self): return iter([]) 1015 self.assertFalse(issubclass(RevNoIter, Reversible)) 1016 self.assertFalse(isinstance(RevNoIter(), Reversible)) 1017 self.assertTrue(issubclass(RevPlusIter, Reversible)) 1018 self.assertTrue(isinstance(RevPlusIter(), Reversible)) 1019 # Check None blocking 1020 class Rev: 1021 def __iter__(self): return iter([]) 1022 def __reversed__(self): return reversed([]) 1023 class RevItBlocked(Rev): 1024 __iter__ = None 1025 class RevRevBlocked(Rev): 1026 __reversed__ = None 1027 self.assertTrue(issubclass(Rev, Reversible)) 1028 self.assertTrue(isinstance(Rev(), Reversible)) 1029 self.assertFalse(issubclass(RevItBlocked, Reversible)) 1030 self.assertFalse(isinstance(RevItBlocked(), Reversible)) 1031 self.assertFalse(issubclass(RevRevBlocked, Reversible)) 1032 self.assertFalse(isinstance(RevRevBlocked(), Reversible)) 1033 1034 def test_Collection(self): 1035 # Check some non-collections 1036 non_collections = [None, 42, 3.14, 1j, lambda x: 2*x] 1037 for x in non_collections: 1038 self.assertNotIsInstance(x, Collection) 1039 self.assertFalse(issubclass(type(x), Collection), repr(type(x))) 1040 # Check some non-collection iterables 1041 non_col_iterables = [_test_gen(), iter(b''), iter(bytearray()), 1042 (x for x in [])] 1043 for x in non_col_iterables: 1044 self.assertNotIsInstance(x, Collection) 1045 self.assertFalse(issubclass(type(x), Collection), repr(type(x))) 1046 # Check some collections 1047 samples = [set(), frozenset(), dict(), bytes(), str(), tuple(), 1048 list(), dict().keys(), dict().items(), dict().values()] 1049 for x in samples: 1050 self.assertIsInstance(x, Collection) 1051 self.assertTrue(issubclass(type(x), Collection), repr(type(x))) 1052 # Check also Mapping, MutableMapping, etc. 1053 self.assertTrue(issubclass(Sequence, Collection), repr(Sequence)) 1054 self.assertTrue(issubclass(Mapping, Collection), repr(Mapping)) 1055 self.assertTrue(issubclass(MutableMapping, Collection), 1056 repr(MutableMapping)) 1057 self.assertTrue(issubclass(Set, Collection), repr(Set)) 1058 self.assertTrue(issubclass(MutableSet, Collection), repr(MutableSet)) 1059 self.assertTrue(issubclass(Sequence, Collection), repr(MutableSet)) 1060 # Check direct subclassing 1061 class Col(Collection): 1062 def __iter__(self): 1063 return iter(list()) 1064 def __len__(self): 1065 return 0 1066 def __contains__(self, item): 1067 return False 1068 class DerCol(Col): pass 1069 self.assertEqual(list(iter(Col())), []) 1070 self.assertFalse(issubclass(list, Col)) 1071 self.assertFalse(issubclass(set, Col)) 1072 self.assertFalse(issubclass(float, Col)) 1073 self.assertEqual(list(iter(DerCol())), []) 1074 self.assertFalse(issubclass(list, DerCol)) 1075 self.assertFalse(issubclass(set, DerCol)) 1076 self.assertFalse(issubclass(float, DerCol)) 1077 self.validate_abstract_methods(Collection, '__len__', '__iter__', 1078 '__contains__') 1079 # Check sized container non-iterable (which is not Collection) etc. 1080 class ColNoIter: 1081 def __len__(self): return 0 1082 def __contains__(self, item): return False 1083 class ColNoSize: 1084 def __iter__(self): return iter([]) 1085 def __contains__(self, item): return False 1086 class ColNoCont: 1087 def __iter__(self): return iter([]) 1088 def __len__(self): return 0 1089 self.assertFalse(issubclass(ColNoIter, Collection)) 1090 self.assertFalse(isinstance(ColNoIter(), Collection)) 1091 self.assertFalse(issubclass(ColNoSize, Collection)) 1092 self.assertFalse(isinstance(ColNoSize(), Collection)) 1093 self.assertFalse(issubclass(ColNoCont, Collection)) 1094 self.assertFalse(isinstance(ColNoCont(), Collection)) 1095 # Check None blocking 1096 class SizeBlock: 1097 def __iter__(self): return iter([]) 1098 def __contains__(self): return False 1099 __len__ = None 1100 class IterBlock: 1101 def __len__(self): return 0 1102 def __contains__(self): return True 1103 __iter__ = None 1104 self.assertFalse(issubclass(SizeBlock, Collection)) 1105 self.assertFalse(isinstance(SizeBlock(), Collection)) 1106 self.assertFalse(issubclass(IterBlock, Collection)) 1107 self.assertFalse(isinstance(IterBlock(), Collection)) 1108 # Check None blocking in subclass 1109 class ColImpl: 1110 def __iter__(self): 1111 return iter(list()) 1112 def __len__(self): 1113 return 0 1114 def __contains__(self, item): 1115 return False 1116 class NonCol(ColImpl): 1117 __contains__ = None 1118 self.assertFalse(issubclass(NonCol, Collection)) 1119 self.assertFalse(isinstance(NonCol(), Collection)) 1120 1121 1122 def test_Iterator(self): 1123 non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] 1124 for x in non_samples: 1125 self.assertNotIsInstance(x, Iterator) 1126 self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) 1127 samples = [iter(bytes()), iter(str()), 1128 iter(tuple()), iter(list()), iter(dict()), 1129 iter(set()), iter(frozenset()), 1130 iter(dict().keys()), iter(dict().items()), 1131 iter(dict().values()), 1132 _test_gen(), 1133 (x for x in []), 1134 ] 1135 for x in samples: 1136 self.assertIsInstance(x, Iterator) 1137 self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) 1138 self.validate_abstract_methods(Iterator, '__next__', '__iter__') 1139 1140 # Issue 10565 1141 class NextOnly: 1142 def __next__(self): 1143 yield 1 1144 return 1145 self.assertNotIsInstance(NextOnly(), Iterator) 1146 1147 def test_Generator(self): 1148 class NonGen1: 1149 def __iter__(self): return self 1150 def __next__(self): return None 1151 def close(self): pass 1152 def throw(self, typ, val=None, tb=None): pass 1153 1154 class NonGen2: 1155 def __iter__(self): return self 1156 def __next__(self): return None 1157 def close(self): pass 1158 def send(self, value): return value 1159 1160 class NonGen3: 1161 def close(self): pass 1162 def send(self, value): return value 1163 def throw(self, typ, val=None, tb=None): pass 1164 1165 non_samples = [ 1166 None, 42, 3.14, 1j, b"", "", (), [], {}, set(), 1167 iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] 1168 for x in non_samples: 1169 self.assertNotIsInstance(x, Generator) 1170 self.assertFalse(issubclass(type(x), Generator), repr(type(x))) 1171 1172 class Gen: 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 def throw(self, typ, val=None, tb=None): pass 1178 1179 class MinimalGen(Generator): 1180 def send(self, value): 1181 return value 1182 def throw(self, typ, val=None, tb=None): 1183 super().throw(typ, val, tb) 1184 1185 def gen(): 1186 yield 1 1187 1188 samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()] 1189 for x in samples: 1190 self.assertIsInstance(x, Iterator) 1191 self.assertIsInstance(x, Generator) 1192 self.assertTrue(issubclass(type(x), Generator), repr(type(x))) 1193 self.validate_abstract_methods(Generator, 'send', 'throw') 1194 1195 # mixin tests 1196 mgen = MinimalGen() 1197 self.assertIs(mgen, iter(mgen)) 1198 self.assertIs(mgen.send(None), next(mgen)) 1199 self.assertEqual(2, mgen.send(2)) 1200 self.assertIsNone(mgen.close()) 1201 self.assertRaises(ValueError, mgen.throw, ValueError) 1202 self.assertRaisesRegex(ValueError, "^huhu$", 1203 mgen.throw, ValueError, ValueError("huhu")) 1204 self.assertRaises(StopIteration, mgen.throw, StopIteration()) 1205 1206 class FailOnClose(Generator): 1207 def send(self, value): return value 1208 def throw(self, *args): raise ValueError 1209 1210 self.assertRaises(ValueError, FailOnClose().close) 1211 1212 class IgnoreGeneratorExit(Generator): 1213 def send(self, value): return value 1214 def throw(self, *args): pass 1215 1216 self.assertRaises(RuntimeError, IgnoreGeneratorExit().close) 1217 1218 def test_AsyncGenerator(self): 1219 class NonAGen1: 1220 def __aiter__(self): return self 1221 def __anext__(self): return None 1222 def aclose(self): pass 1223 def athrow(self, typ, val=None, tb=None): pass 1224 1225 class NonAGen2: 1226 def __aiter__(self): return self 1227 def __anext__(self): return None 1228 def aclose(self): pass 1229 def asend(self, value): return value 1230 1231 class NonAGen3: 1232 def aclose(self): pass 1233 def asend(self, value): return value 1234 def athrow(self, typ, val=None, tb=None): pass 1235 1236 non_samples = [ 1237 None, 42, 3.14, 1j, b"", "", (), [], {}, set(), 1238 iter(()), iter([]), NonAGen1(), NonAGen2(), NonAGen3()] 1239 for x in non_samples: 1240 self.assertNotIsInstance(x, AsyncGenerator) 1241 self.assertFalse(issubclass(type(x), AsyncGenerator), repr(type(x))) 1242 1243 class Gen: 1244 def __aiter__(self): return self 1245 async def __anext__(self): return None 1246 async def aclose(self): pass 1247 async def asend(self, value): return value 1248 async def athrow(self, typ, val=None, tb=None): pass 1249 1250 class MinimalAGen(AsyncGenerator): 1251 async def asend(self, value): 1252 return value 1253 async def athrow(self, typ, val=None, tb=None): 1254 await super().athrow(typ, val, tb) 1255 1256 async def gen(): 1257 yield 1 1258 1259 samples = [gen(), Gen(), MinimalAGen()] 1260 for x in samples: 1261 self.assertIsInstance(x, AsyncIterator) 1262 self.assertIsInstance(x, AsyncGenerator) 1263 self.assertTrue(issubclass(type(x), AsyncGenerator), repr(type(x))) 1264 self.validate_abstract_methods(AsyncGenerator, 'asend', 'athrow') 1265 1266 def run_async(coro): 1267 result = None 1268 while True: 1269 try: 1270 coro.send(None) 1271 except StopIteration as ex: 1272 result = ex.args[0] if ex.args else None 1273 break 1274 return result 1275 1276 # mixin tests 1277 mgen = MinimalAGen() 1278 self.assertIs(mgen, mgen.__aiter__()) 1279 self.assertIs(run_async(mgen.asend(None)), run_async(mgen.__anext__())) 1280 self.assertEqual(2, run_async(mgen.asend(2))) 1281 self.assertIsNone(run_async(mgen.aclose())) 1282 with self.assertRaises(ValueError): 1283 run_async(mgen.athrow(ValueError)) 1284 1285 class FailOnClose(AsyncGenerator): 1286 async def asend(self, value): return value 1287 async def athrow(self, *args): raise ValueError 1288 1289 with self.assertRaises(ValueError): 1290 run_async(FailOnClose().aclose()) 1291 1292 class IgnoreGeneratorExit(AsyncGenerator): 1293 async def asend(self, value): return value 1294 async def athrow(self, *args): pass 1295 1296 with self.assertRaises(RuntimeError): 1297 run_async(IgnoreGeneratorExit().aclose()) 1298 1299 def test_Sized(self): 1300 non_samples = [None, 42, 3.14, 1j, 1301 _test_gen(), 1302 (x for x in []), 1303 ] 1304 for x in non_samples: 1305 self.assertNotIsInstance(x, Sized) 1306 self.assertFalse(issubclass(type(x), Sized), repr(type(x))) 1307 samples = [bytes(), str(), 1308 tuple(), list(), set(), frozenset(), dict(), 1309 dict().keys(), dict().items(), dict().values(), 1310 ] 1311 for x in samples: 1312 self.assertIsInstance(x, Sized) 1313 self.assertTrue(issubclass(type(x), Sized), repr(type(x))) 1314 self.validate_abstract_methods(Sized, '__len__') 1315 self.validate_isinstance(Sized, '__len__') 1316 1317 def test_Container(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, Container) 1324 self.assertFalse(issubclass(type(x), Container), repr(type(x))) 1325 samples = [bytes(), str(), 1326 tuple(), list(), set(), frozenset(), dict(), 1327 dict().keys(), dict().items(), 1328 ] 1329 for x in samples: 1330 self.assertIsInstance(x, Container) 1331 self.assertTrue(issubclass(type(x), Container), repr(type(x))) 1332 self.validate_abstract_methods(Container, '__contains__') 1333 self.validate_isinstance(Container, '__contains__') 1334 1335 def test_Callable(self): 1336 non_samples = [None, 42, 3.14, 1j, 1337 "", b"", (), [], {}, set(), 1338 _test_gen(), 1339 (x for x in []), 1340 ] 1341 for x in non_samples: 1342 self.assertNotIsInstance(x, Callable) 1343 self.assertFalse(issubclass(type(x), Callable), repr(type(x))) 1344 samples = [lambda: None, 1345 type, int, object, 1346 len, 1347 list.append, [].append, 1348 ] 1349 for x in samples: 1350 self.assertIsInstance(x, Callable) 1351 self.assertTrue(issubclass(type(x), Callable), repr(type(x))) 1352 self.validate_abstract_methods(Callable, '__call__') 1353 self.validate_isinstance(Callable, '__call__') 1354 1355 def test_direct_subclassing(self): 1356 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: 1357 class C(B): 1358 pass 1359 self.assertTrue(issubclass(C, B)) 1360 self.assertFalse(issubclass(int, C)) 1361 1362 def test_registration(self): 1363 for B in Hashable, Iterable, Iterator, Reversible, Sized, Container, Callable: 1364 class C: 1365 __hash__ = None # Make sure it isn't hashable by default 1366 self.assertFalse(issubclass(C, B), B.__name__) 1367 B.register(C) 1368 self.assertTrue(issubclass(C, B)) 1369 1370class WithSet(MutableSet): 1371 1372 def __init__(self, it=()): 1373 self.data = set(it) 1374 1375 def __len__(self): 1376 return len(self.data) 1377 1378 def __iter__(self): 1379 return iter(self.data) 1380 1381 def __contains__(self, item): 1382 return item in self.data 1383 1384 def add(self, item): 1385 self.data.add(item) 1386 1387 def discard(self, item): 1388 self.data.discard(item) 1389 1390class TestCollectionABCs(ABCTestCase): 1391 1392 # XXX For now, we only test some virtual inheritance properties. 1393 # We should also test the proper behavior of the collection ABCs 1394 # as real base classes or mix-in classes. 1395 1396 def test_Set(self): 1397 for sample in [set, frozenset]: 1398 self.assertIsInstance(sample(), Set) 1399 self.assertTrue(issubclass(sample, Set)) 1400 self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') 1401 class MySet(Set): 1402 def __contains__(self, x): 1403 return False 1404 def __len__(self): 1405 return 0 1406 def __iter__(self): 1407 return iter([]) 1408 self.validate_comparison(MySet()) 1409 1410 def test_hash_Set(self): 1411 class OneTwoThreeSet(Set): 1412 def __init__(self): 1413 self.contents = [1, 2, 3] 1414 def __contains__(self, x): 1415 return x in self.contents 1416 def __len__(self): 1417 return len(self.contents) 1418 def __iter__(self): 1419 return iter(self.contents) 1420 def __hash__(self): 1421 return self._hash() 1422 a, b = OneTwoThreeSet(), OneTwoThreeSet() 1423 self.assertTrue(hash(a) == hash(b)) 1424 1425 def test_isdisjoint_Set(self): 1426 class MySet(Set): 1427 def __init__(self, itr): 1428 self.contents = itr 1429 def __contains__(self, x): 1430 return x in self.contents 1431 def __iter__(self): 1432 return iter(self.contents) 1433 def __len__(self): 1434 return len([x for x in self.contents]) 1435 s1 = MySet((1, 2, 3)) 1436 s2 = MySet((4, 5, 6)) 1437 s3 = MySet((1, 5, 6)) 1438 self.assertTrue(s1.isdisjoint(s2)) 1439 self.assertFalse(s1.isdisjoint(s3)) 1440 1441 def test_equality_Set(self): 1442 class MySet(Set): 1443 def __init__(self, itr): 1444 self.contents = itr 1445 def __contains__(self, x): 1446 return x in self.contents 1447 def __iter__(self): 1448 return iter(self.contents) 1449 def __len__(self): 1450 return len([x for x in self.contents]) 1451 s1 = MySet((1,)) 1452 s2 = MySet((1, 2)) 1453 s3 = MySet((3, 4)) 1454 s4 = MySet((3, 4)) 1455 self.assertTrue(s2 > s1) 1456 self.assertTrue(s1 < s2) 1457 self.assertFalse(s2 <= s1) 1458 self.assertFalse(s2 <= s3) 1459 self.assertFalse(s1 >= s2) 1460 self.assertEqual(s3, s4) 1461 self.assertNotEqual(s2, s3) 1462 1463 def test_arithmetic_Set(self): 1464 class MySet(Set): 1465 def __init__(self, itr): 1466 self.contents = itr 1467 def __contains__(self, x): 1468 return x in self.contents 1469 def __iter__(self): 1470 return iter(self.contents) 1471 def __len__(self): 1472 return len([x for x in self.contents]) 1473 s1 = MySet((1, 2, 3)) 1474 s2 = MySet((3, 4, 5)) 1475 s3 = s1 & s2 1476 self.assertEqual(s3, MySet((3,))) 1477 1478 def test_MutableSet(self): 1479 self.assertIsInstance(set(), MutableSet) 1480 self.assertTrue(issubclass(set, MutableSet)) 1481 self.assertNotIsInstance(frozenset(), MutableSet) 1482 self.assertFalse(issubclass(frozenset, MutableSet)) 1483 self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 1484 'add', 'discard') 1485 1486 def test_issue_5647(self): 1487 # MutableSet.__iand__ mutated the set during iteration 1488 s = WithSet('abcd') 1489 s &= WithSet('cdef') # This used to fail 1490 self.assertEqual(set(s), set('cd')) 1491 1492 def test_issue_4920(self): 1493 # MutableSet.pop() method did not work 1494 class MySet(MutableSet): 1495 __slots__=['__s'] 1496 def __init__(self,items=None): 1497 if items is None: 1498 items=[] 1499 self.__s=set(items) 1500 def __contains__(self,v): 1501 return v in self.__s 1502 def __iter__(self): 1503 return iter(self.__s) 1504 def __len__(self): 1505 return len(self.__s) 1506 def add(self,v): 1507 result=v not in self.__s 1508 self.__s.add(v) 1509 return result 1510 def discard(self,v): 1511 result=v in self.__s 1512 self.__s.discard(v) 1513 return result 1514 def __repr__(self): 1515 return "MySet(%s)" % repr(list(self)) 1516 items = [5,43,2,1] 1517 s = MySet(items) 1518 r = s.pop() 1519 self.assertEqual(len(s), len(items) - 1) 1520 self.assertNotIn(r, s) 1521 self.assertIn(r, items) 1522 1523 def test_issue8750(self): 1524 empty = WithSet() 1525 full = WithSet(range(10)) 1526 s = WithSet(full) 1527 s -= s 1528 self.assertEqual(s, empty) 1529 s = WithSet(full) 1530 s ^= s 1531 self.assertEqual(s, empty) 1532 s = WithSet(full) 1533 s &= s 1534 self.assertEqual(s, full) 1535 s |= s 1536 self.assertEqual(s, full) 1537 1538 def test_issue16373(self): 1539 # Recursion error comparing comparable and noncomparable 1540 # Set instances 1541 class MyComparableSet(Set): 1542 def __contains__(self, x): 1543 return False 1544 def __len__(self): 1545 return 0 1546 def __iter__(self): 1547 return iter([]) 1548 class MyNonComparableSet(Set): 1549 def __contains__(self, x): 1550 return False 1551 def __len__(self): 1552 return 0 1553 def __iter__(self): 1554 return iter([]) 1555 def __le__(self, x): 1556 return NotImplemented 1557 def __lt__(self, x): 1558 return NotImplemented 1559 1560 cs = MyComparableSet() 1561 ncs = MyNonComparableSet() 1562 self.assertFalse(ncs < cs) 1563 self.assertTrue(ncs <= cs) 1564 self.assertFalse(ncs > cs) 1565 self.assertTrue(ncs >= cs) 1566 1567 def test_issue26915(self): 1568 # Container membership test should check identity first 1569 class CustomSequence(Sequence): 1570 def __init__(self, seq): 1571 self._seq = seq 1572 def __getitem__(self, index): 1573 return self._seq[index] 1574 def __len__(self): 1575 return len(self._seq) 1576 1577 nan = float('nan') 1578 obj = support.NEVER_EQ 1579 seq = CustomSequence([nan, obj, nan]) 1580 containers = [ 1581 seq, 1582 ItemsView({1: nan, 2: obj}), 1583 ValuesView({1: nan, 2: obj}) 1584 ] 1585 for container in containers: 1586 for elem in container: 1587 self.assertIn(elem, container) 1588 self.assertEqual(seq.index(nan), 0) 1589 self.assertEqual(seq.index(obj), 1) 1590 self.assertEqual(seq.count(nan), 2) 1591 self.assertEqual(seq.count(obj), 1) 1592 1593 def assertSameSet(self, s1, s2): 1594 # coerce both to a real set then check equality 1595 self.assertSetEqual(set(s1), set(s2)) 1596 1597 def test_Set_from_iterable(self): 1598 """Verify _from_iterable overridden to an instance method works.""" 1599 class SetUsingInstanceFromIterable(MutableSet): 1600 def __init__(self, values, created_by): 1601 if not created_by: 1602 raise ValueError(f'created_by must be specified') 1603 self.created_by = created_by 1604 self._values = set(values) 1605 1606 def _from_iterable(self, values): 1607 return type(self)(values, 'from_iterable') 1608 1609 def __contains__(self, value): 1610 return value in self._values 1611 1612 def __iter__(self): 1613 yield from self._values 1614 1615 def __len__(self): 1616 return len(self._values) 1617 1618 def add(self, value): 1619 self._values.add(value) 1620 1621 def discard(self, value): 1622 self._values.discard(value) 1623 1624 impl = SetUsingInstanceFromIterable([1, 2, 3], 'test') 1625 1626 actual = impl - {1} 1627 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1628 self.assertEqual('from_iterable', actual.created_by) 1629 self.assertEqual({2, 3}, actual) 1630 1631 actual = impl | {4} 1632 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1633 self.assertEqual('from_iterable', actual.created_by) 1634 self.assertEqual({1, 2, 3, 4}, actual) 1635 1636 actual = impl & {2} 1637 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1638 self.assertEqual('from_iterable', actual.created_by) 1639 self.assertEqual({2}, actual) 1640 1641 actual = impl ^ {3, 4} 1642 self.assertIsInstance(actual, SetUsingInstanceFromIterable) 1643 self.assertEqual('from_iterable', actual.created_by) 1644 self.assertEqual({1, 2, 4}, actual) 1645 1646 # NOTE: ixor'ing with a list is important here: internally, __ixor__ 1647 # only calls _from_iterable if the other value isn't already a Set. 1648 impl ^= [3, 4] 1649 self.assertIsInstance(impl, SetUsingInstanceFromIterable) 1650 self.assertEqual('test', impl.created_by) 1651 self.assertEqual({1, 2, 4}, impl) 1652 1653 def test_Set_interoperability_with_real_sets(self): 1654 # Issue: 8743 1655 class ListSet(Set): 1656 def __init__(self, elements=()): 1657 self.data = [] 1658 for elem in elements: 1659 if elem not in self.data: 1660 self.data.append(elem) 1661 def __contains__(self, elem): 1662 return elem in self.data 1663 def __iter__(self): 1664 return iter(self.data) 1665 def __len__(self): 1666 return len(self.data) 1667 def __repr__(self): 1668 return 'Set({!r})'.format(self.data) 1669 1670 r1 = set('abc') 1671 r2 = set('bcd') 1672 r3 = set('abcde') 1673 f1 = ListSet('abc') 1674 f2 = ListSet('bcd') 1675 f3 = ListSet('abcde') 1676 l1 = list('abccba') 1677 l2 = list('bcddcb') 1678 l3 = list('abcdeedcba') 1679 1680 target = r1 & r2 1681 self.assertSameSet(f1 & f2, target) 1682 self.assertSameSet(f1 & r2, target) 1683 self.assertSameSet(r2 & f1, target) 1684 self.assertSameSet(f1 & l2, target) 1685 1686 target = r1 | r2 1687 self.assertSameSet(f1 | f2, target) 1688 self.assertSameSet(f1 | r2, target) 1689 self.assertSameSet(r2 | f1, target) 1690 self.assertSameSet(f1 | l2, target) 1691 1692 fwd_target = r1 - r2 1693 rev_target = r2 - r1 1694 self.assertSameSet(f1 - f2, fwd_target) 1695 self.assertSameSet(f2 - f1, rev_target) 1696 self.assertSameSet(f1 - r2, fwd_target) 1697 self.assertSameSet(f2 - r1, rev_target) 1698 self.assertSameSet(r1 - f2, fwd_target) 1699 self.assertSameSet(r2 - f1, rev_target) 1700 self.assertSameSet(f1 - l2, fwd_target) 1701 self.assertSameSet(f2 - l1, rev_target) 1702 1703 target = r1 ^ r2 1704 self.assertSameSet(f1 ^ f2, target) 1705 self.assertSameSet(f1 ^ r2, target) 1706 self.assertSameSet(r2 ^ f1, target) 1707 self.assertSameSet(f1 ^ l2, target) 1708 1709 # Don't change the following to use assertLess or other 1710 # "more specific" unittest assertions. The current 1711 # assertTrue/assertFalse style makes the pattern of test 1712 # case combinations clear and allows us to know for sure 1713 # the exact operator being invoked. 1714 1715 # proper subset 1716 self.assertTrue(f1 < f3) 1717 self.assertFalse(f1 < f1) 1718 self.assertFalse(f1 < f2) 1719 self.assertTrue(r1 < f3) 1720 self.assertFalse(r1 < f1) 1721 self.assertFalse(r1 < f2) 1722 self.assertTrue(r1 < r3) 1723 self.assertFalse(r1 < r1) 1724 self.assertFalse(r1 < r2) 1725 with self.assertRaises(TypeError): 1726 f1 < l3 1727 with self.assertRaises(TypeError): 1728 f1 < l1 1729 with self.assertRaises(TypeError): 1730 f1 < l2 1731 1732 # any subset 1733 self.assertTrue(f1 <= f3) 1734 self.assertTrue(f1 <= f1) 1735 self.assertFalse(f1 <= f2) 1736 self.assertTrue(r1 <= f3) 1737 self.assertTrue(r1 <= f1) 1738 self.assertFalse(r1 <= f2) 1739 self.assertTrue(r1 <= r3) 1740 self.assertTrue(r1 <= r1) 1741 self.assertFalse(r1 <= r2) 1742 with self.assertRaises(TypeError): 1743 f1 <= l3 1744 with self.assertRaises(TypeError): 1745 f1 <= l1 1746 with self.assertRaises(TypeError): 1747 f1 <= l2 1748 1749 # proper superset 1750 self.assertTrue(f3 > f1) 1751 self.assertFalse(f1 > f1) 1752 self.assertFalse(f2 > f1) 1753 self.assertTrue(r3 > r1) 1754 self.assertFalse(f1 > r1) 1755 self.assertFalse(f2 > r1) 1756 self.assertTrue(r3 > r1) 1757 self.assertFalse(r1 > r1) 1758 self.assertFalse(r2 > r1) 1759 with self.assertRaises(TypeError): 1760 f1 > l3 1761 with self.assertRaises(TypeError): 1762 f1 > l1 1763 with self.assertRaises(TypeError): 1764 f1 > l2 1765 1766 # any superset 1767 self.assertTrue(f3 >= f1) 1768 self.assertTrue(f1 >= f1) 1769 self.assertFalse(f2 >= f1) 1770 self.assertTrue(r3 >= r1) 1771 self.assertTrue(f1 >= r1) 1772 self.assertFalse(f2 >= r1) 1773 self.assertTrue(r3 >= r1) 1774 self.assertTrue(r1 >= r1) 1775 self.assertFalse(r2 >= r1) 1776 with self.assertRaises(TypeError): 1777 f1 >= l3 1778 with self.assertRaises(TypeError): 1779 f1 >=l1 1780 with self.assertRaises(TypeError): 1781 f1 >= l2 1782 1783 # equality 1784 self.assertTrue(f1 == f1) 1785 self.assertTrue(r1 == f1) 1786 self.assertTrue(f1 == r1) 1787 self.assertFalse(f1 == f3) 1788 self.assertFalse(r1 == f3) 1789 self.assertFalse(f1 == r3) 1790 self.assertFalse(f1 == l3) 1791 self.assertFalse(f1 == l1) 1792 self.assertFalse(f1 == l2) 1793 1794 # inequality 1795 self.assertFalse(f1 != f1) 1796 self.assertFalse(r1 != f1) 1797 self.assertFalse(f1 != r1) 1798 self.assertTrue(f1 != f3) 1799 self.assertTrue(r1 != f3) 1800 self.assertTrue(f1 != r3) 1801 self.assertTrue(f1 != l3) 1802 self.assertTrue(f1 != l1) 1803 self.assertTrue(f1 != l2) 1804 1805 def test_Set_hash_matches_frozenset(self): 1806 sets = [ 1807 {}, {1}, {None}, {-1}, {0.0}, {"abc"}, {1, 2, 3}, 1808 {10**100, 10**101}, {"a", "b", "ab", ""}, {False, True}, 1809 {object(), object(), object()}, {float("nan")}, {frozenset()}, 1810 {*range(1000)}, {*range(1000)} - {100, 200, 300}, 1811 {*range(sys.maxsize - 10, sys.maxsize + 10)}, 1812 ] 1813 for s in sets: 1814 fs = frozenset(s) 1815 self.assertEqual(hash(fs), Set._hash(fs), msg=s) 1816 1817 def test_Mapping(self): 1818 for sample in [dict]: 1819 self.assertIsInstance(sample(), Mapping) 1820 self.assertTrue(issubclass(sample, Mapping)) 1821 self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', 1822 '__getitem__') 1823 class MyMapping(Mapping): 1824 def __len__(self): 1825 return 0 1826 def __getitem__(self, i): 1827 raise IndexError 1828 def __iter__(self): 1829 return iter(()) 1830 self.validate_comparison(MyMapping()) 1831 self.assertRaises(TypeError, reversed, MyMapping()) 1832 1833 def test_MutableMapping(self): 1834 for sample in [dict]: 1835 self.assertIsInstance(sample(), MutableMapping) 1836 self.assertTrue(issubclass(sample, MutableMapping)) 1837 self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', 1838 '__getitem__', '__setitem__', '__delitem__') 1839 1840 def test_MutableMapping_subclass(self): 1841 # Test issue 9214 1842 mymap = UserDict() 1843 mymap['red'] = 5 1844 self.assertIsInstance(mymap.keys(), Set) 1845 self.assertIsInstance(mymap.keys(), KeysView) 1846 self.assertIsInstance(mymap.items(), Set) 1847 self.assertIsInstance(mymap.items(), ItemsView) 1848 1849 mymap = UserDict() 1850 mymap['red'] = 5 1851 z = mymap.keys() | {'orange'} 1852 self.assertIsInstance(z, set) 1853 list(z) 1854 mymap['blue'] = 7 # Shouldn't affect 'z' 1855 self.assertEqual(sorted(z), ['orange', 'red']) 1856 1857 mymap = UserDict() 1858 mymap['red'] = 5 1859 z = mymap.items() | {('orange', 3)} 1860 self.assertIsInstance(z, set) 1861 list(z) 1862 mymap['blue'] = 7 # Shouldn't affect 'z' 1863 self.assertEqual(z, {('orange', 3), ('red', 5)}) 1864 1865 def test_Sequence(self): 1866 for sample in [tuple, list, bytes, str]: 1867 self.assertIsInstance(sample(), Sequence) 1868 self.assertTrue(issubclass(sample, Sequence)) 1869 self.assertIsInstance(range(10), Sequence) 1870 self.assertTrue(issubclass(range, Sequence)) 1871 self.assertIsInstance(memoryview(b""), Sequence) 1872 self.assertTrue(issubclass(memoryview, Sequence)) 1873 self.assertTrue(issubclass(str, Sequence)) 1874 self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', 1875 '__getitem__') 1876 1877 def test_Sequence_mixins(self): 1878 class SequenceSubclass(Sequence): 1879 def __init__(self, seq=()): 1880 self.seq = seq 1881 1882 def __getitem__(self, index): 1883 return self.seq[index] 1884 1885 def __len__(self): 1886 return len(self.seq) 1887 1888 # Compare Sequence.index() behavior to (list|str).index() behavior 1889 def assert_index_same(seq1, seq2, index_args): 1890 try: 1891 expected = seq1.index(*index_args) 1892 except ValueError: 1893 with self.assertRaises(ValueError): 1894 seq2.index(*index_args) 1895 else: 1896 actual = seq2.index(*index_args) 1897 self.assertEqual( 1898 actual, expected, '%r.index%s' % (seq1, index_args)) 1899 1900 for ty in list, str: 1901 nativeseq = ty('abracadabra') 1902 indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3)) 1903 seqseq = SequenceSubclass(nativeseq) 1904 for letter in set(nativeseq) | {'z'}: 1905 assert_index_same(nativeseq, seqseq, (letter,)) 1906 for start in range(-3, len(nativeseq) + 3): 1907 assert_index_same(nativeseq, seqseq, (letter, start)) 1908 for stop in range(-3, len(nativeseq) + 3): 1909 assert_index_same( 1910 nativeseq, seqseq, (letter, start, stop)) 1911 1912 def test_ByteString(self): 1913 for sample in [bytes, bytearray]: 1914 self.assertIsInstance(sample(), ByteString) 1915 self.assertTrue(issubclass(sample, ByteString)) 1916 for sample in [str, list, tuple]: 1917 self.assertNotIsInstance(sample(), ByteString) 1918 self.assertFalse(issubclass(sample, ByteString)) 1919 self.assertNotIsInstance(memoryview(b""), ByteString) 1920 self.assertFalse(issubclass(memoryview, ByteString)) 1921 1922 def test_MutableSequence(self): 1923 for sample in [tuple, str, bytes]: 1924 self.assertNotIsInstance(sample(), MutableSequence) 1925 self.assertFalse(issubclass(sample, MutableSequence)) 1926 for sample in [list, bytearray, deque]: 1927 self.assertIsInstance(sample(), MutableSequence) 1928 self.assertTrue(issubclass(sample, MutableSequence)) 1929 self.assertFalse(issubclass(str, MutableSequence)) 1930 self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', 1931 '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') 1932 1933 def test_MutableSequence_mixins(self): 1934 # Test the mixins of MutableSequence by creating a minimal concrete 1935 # class inherited from it. 1936 class MutableSequenceSubclass(MutableSequence): 1937 def __init__(self): 1938 self.lst = [] 1939 1940 def __setitem__(self, index, value): 1941 self.lst[index] = value 1942 1943 def __getitem__(self, index): 1944 return self.lst[index] 1945 1946 def __len__(self): 1947 return len(self.lst) 1948 1949 def __delitem__(self, index): 1950 del self.lst[index] 1951 1952 def insert(self, index, value): 1953 self.lst.insert(index, value) 1954 1955 mss = MutableSequenceSubclass() 1956 mss.append(0) 1957 mss.extend((1, 2, 3, 4)) 1958 self.assertEqual(len(mss), 5) 1959 self.assertEqual(mss[3], 3) 1960 mss.reverse() 1961 self.assertEqual(mss[3], 1) 1962 mss.pop() 1963 self.assertEqual(len(mss), 4) 1964 mss.remove(3) 1965 self.assertEqual(len(mss), 3) 1966 mss += (10, 20, 30) 1967 self.assertEqual(len(mss), 6) 1968 self.assertEqual(mss[-1], 30) 1969 mss.clear() 1970 self.assertEqual(len(mss), 0) 1971 1972 # issue 34427 1973 # extending self should not cause infinite loop 1974 items = 'ABCD' 1975 mss2 = MutableSequenceSubclass() 1976 mss2.extend(items + items) 1977 mss.clear() 1978 mss.extend(items) 1979 mss.extend(mss) 1980 self.assertEqual(len(mss), len(mss2)) 1981 self.assertEqual(list(mss), list(mss2)) 1982 1983 def test_illegal_patma_flags(self): 1984 with self.assertRaises(TypeError): 1985 class Both(Collection): 1986 __abc_tpflags__ = (Sequence.__flags__ | Mapping.__flags__) 1987 1988 1989 1990################################################################################ 1991### Counter 1992################################################################################ 1993 1994class CounterSubclassWithSetItem(Counter): 1995 # Test a counter subclass that overrides __setitem__ 1996 def __init__(self, *args, **kwds): 1997 self.called = False 1998 Counter.__init__(self, *args, **kwds) 1999 def __setitem__(self, key, value): 2000 self.called = True 2001 Counter.__setitem__(self, key, value) 2002 2003class CounterSubclassWithGet(Counter): 2004 # Test a counter subclass that overrides get() 2005 def __init__(self, *args, **kwds): 2006 self.called = False 2007 Counter.__init__(self, *args, **kwds) 2008 def get(self, key, default): 2009 self.called = True 2010 return Counter.get(self, key, default) 2011 2012class TestCounter(unittest.TestCase): 2013 2014 def test_basics(self): 2015 c = Counter('abcaba') 2016 self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) 2017 self.assertEqual(c, Counter(a=3, b=2, c=1)) 2018 self.assertIsInstance(c, dict) 2019 self.assertIsInstance(c, Mapping) 2020 self.assertTrue(issubclass(Counter, dict)) 2021 self.assertTrue(issubclass(Counter, Mapping)) 2022 self.assertEqual(len(c), 3) 2023 self.assertEqual(sum(c.values()), 6) 2024 self.assertEqual(list(c.values()), [3, 2, 1]) 2025 self.assertEqual(list(c.keys()), ['a', 'b', 'c']) 2026 self.assertEqual(list(c), ['a', 'b', 'c']) 2027 self.assertEqual(list(c.items()), 2028 [('a', 3), ('b', 2), ('c', 1)]) 2029 self.assertEqual(c['b'], 2) 2030 self.assertEqual(c['z'], 0) 2031 self.assertEqual(c.__contains__('c'), True) 2032 self.assertEqual(c.__contains__('z'), False) 2033 self.assertEqual(c.get('b', 10), 2) 2034 self.assertEqual(c.get('z', 10), 10) 2035 self.assertEqual(c, dict(a=3, b=2, c=1)) 2036 self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") 2037 self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) 2038 for i in range(5): 2039 self.assertEqual(c.most_common(i), 2040 [('a', 3), ('b', 2), ('c', 1)][:i]) 2041 self.assertEqual(''.join(c.elements()), 'aaabbc') 2042 c['a'] += 1 # increment an existing value 2043 c['b'] -= 2 # sub existing value to zero 2044 del c['c'] # remove an entry 2045 del c['c'] # make sure that del doesn't raise KeyError 2046 c['d'] -= 2 # sub from a missing value 2047 c['e'] = -5 # directly assign a missing value 2048 c['f'] += 4 # add to a missing value 2049 self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) 2050 self.assertEqual(''.join(c.elements()), 'aaaaffff') 2051 self.assertEqual(c.pop('f'), 4) 2052 self.assertNotIn('f', c) 2053 for i in range(3): 2054 elem, cnt = c.popitem() 2055 self.assertNotIn(elem, c) 2056 c.clear() 2057 self.assertEqual(c, {}) 2058 self.assertEqual(repr(c), 'Counter()') 2059 self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') 2060 self.assertRaises(TypeError, hash, c) 2061 c.update(dict(a=5, b=3)) 2062 c.update(c=1) 2063 c.update(Counter('a' * 50 + 'b' * 30)) 2064 c.update() # test case with no args 2065 c.__init__('a' * 500 + 'b' * 300) 2066 c.__init__('cdc') 2067 c.__init__() 2068 self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) 2069 self.assertEqual(c.setdefault('d', 5), 1) 2070 self.assertEqual(c['d'], 1) 2071 self.assertEqual(c.setdefault('e', 5), 5) 2072 self.assertEqual(c['e'], 5) 2073 2074 def test_init(self): 2075 self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) 2076 self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) 2077 self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) 2078 self.assertRaises(TypeError, Counter, 42) 2079 self.assertRaises(TypeError, Counter, (), ()) 2080 self.assertRaises(TypeError, Counter.__init__) 2081 2082 def test_total(self): 2083 c = Counter(a=10, b=5, c=0) 2084 self.assertEqual(c.total(), 15) 2085 2086 def test_order_preservation(self): 2087 # Input order dictates items() order 2088 self.assertEqual(list(Counter('abracadabra').items()), 2089 [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]) 2090 # letters with same count: ^----------^ ^---------^ 2091 2092 # Verify retention of order even when all counts are equal 2093 self.assertEqual(list(Counter('xyzpdqqdpzyx').items()), 2094 [('x', 2), ('y', 2), ('z', 2), ('p', 2), ('d', 2), ('q', 2)]) 2095 2096 # Input order dictates elements() order 2097 self.assertEqual(list(Counter('abracadabra simsalabim').elements()), 2098 ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'b','r', 2099 'r', 'c', 'd', ' ', 's', 's', 'i', 'i', 'm', 'm', 'l']) 2100 2101 # Math operations order first by the order encountered in the left 2102 # operand and then by the order encountered in the right operand. 2103 ps = 'aaabbcdddeefggghhijjjkkl' 2104 qs = 'abbcccdeefffhkkllllmmnno' 2105 order = {letter: i for i, letter in enumerate(dict.fromkeys(ps + qs))} 2106 def correctly_ordered(seq): 2107 'Return true if the letters occur in the expected order' 2108 positions = [order[letter] for letter in seq] 2109 return positions == sorted(positions) 2110 2111 p, q = Counter(ps), Counter(qs) 2112 self.assertTrue(correctly_ordered(+p)) 2113 self.assertTrue(correctly_ordered(-p)) 2114 self.assertTrue(correctly_ordered(p + q)) 2115 self.assertTrue(correctly_ordered(p - q)) 2116 self.assertTrue(correctly_ordered(p | q)) 2117 self.assertTrue(correctly_ordered(p & q)) 2118 2119 p, q = Counter(ps), Counter(qs) 2120 p += q 2121 self.assertTrue(correctly_ordered(p)) 2122 2123 p, q = Counter(ps), Counter(qs) 2124 p -= q 2125 self.assertTrue(correctly_ordered(p)) 2126 2127 p, q = Counter(ps), Counter(qs) 2128 p |= q 2129 self.assertTrue(correctly_ordered(p)) 2130 2131 p, q = Counter(ps), Counter(qs) 2132 p &= q 2133 self.assertTrue(correctly_ordered(p)) 2134 2135 p, q = Counter(ps), Counter(qs) 2136 p.update(q) 2137 self.assertTrue(correctly_ordered(p)) 2138 2139 p, q = Counter(ps), Counter(qs) 2140 p.subtract(q) 2141 self.assertTrue(correctly_ordered(p)) 2142 2143 def test_update(self): 2144 c = Counter() 2145 c.update(self=42) 2146 self.assertEqual(list(c.items()), [('self', 42)]) 2147 c = Counter() 2148 c.update(iterable=42) 2149 self.assertEqual(list(c.items()), [('iterable', 42)]) 2150 c = Counter() 2151 c.update(iterable=None) 2152 self.assertEqual(list(c.items()), [('iterable', None)]) 2153 self.assertRaises(TypeError, Counter().update, 42) 2154 self.assertRaises(TypeError, Counter().update, {}, {}) 2155 self.assertRaises(TypeError, Counter.update) 2156 2157 def test_copying(self): 2158 # Check that counters are copyable, deepcopyable, picklable, and 2159 #have a repr/eval round-trip 2160 words = Counter('which witch had which witches wrist watch'.split()) 2161 def check(dup): 2162 msg = "\ncopy: %s\nwords: %s" % (dup, words) 2163 self.assertIsNot(dup, words, msg) 2164 self.assertEqual(dup, words) 2165 check(words.copy()) 2166 check(copy.copy(words)) 2167 check(copy.deepcopy(words)) 2168 for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2169 with self.subTest(proto=proto): 2170 check(pickle.loads(pickle.dumps(words, proto))) 2171 check(eval(repr(words))) 2172 update_test = Counter() 2173 update_test.update(words) 2174 check(update_test) 2175 check(Counter(words)) 2176 2177 def test_copy_subclass(self): 2178 class MyCounter(Counter): 2179 pass 2180 c = MyCounter('slartibartfast') 2181 d = c.copy() 2182 self.assertEqual(d, c) 2183 self.assertEqual(len(d), len(c)) 2184 self.assertEqual(type(d), type(c)) 2185 2186 def test_conversions(self): 2187 # Convert to: set, list, dict 2188 s = 'she sells sea shells by the sea shore' 2189 self.assertEqual(sorted(Counter(s).elements()), sorted(s)) 2190 self.assertEqual(sorted(Counter(s)), sorted(set(s))) 2191 self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) 2192 self.assertEqual(set(Counter(s)), set(s)) 2193 2194 def test_invariant_for_the_in_operator(self): 2195 c = Counter(a=10, b=-2, c=0) 2196 for elem in c: 2197 self.assertTrue(elem in c) 2198 self.assertIn(elem, c) 2199 2200 def test_multiset_operations(self): 2201 # Verify that adding a zero counter will strip zeros and negatives 2202 c = Counter(a=10, b=-2, c=0) + Counter() 2203 self.assertEqual(dict(c), dict(a=10)) 2204 2205 elements = 'abcd' 2206 for i in range(1000): 2207 # test random pairs of multisets 2208 p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2209 p.update(e=1, f=-1, g=0) 2210 q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2211 q.update(h=1, i=-1, j=0) 2212 for counterop, numberop in [ 2213 (Counter.__add__, lambda x, y: max(0, x+y)), 2214 (Counter.__sub__, lambda x, y: max(0, x-y)), 2215 (Counter.__or__, lambda x, y: max(0,x,y)), 2216 (Counter.__and__, lambda x, y: max(0, min(x,y))), 2217 ]: 2218 result = counterop(p, q) 2219 for x in elements: 2220 self.assertEqual(numberop(p[x], q[x]), result[x], 2221 (counterop, x, p, q)) 2222 # verify that results exclude non-positive counts 2223 self.assertTrue(x>0 for x in result.values()) 2224 2225 elements = 'abcdef' 2226 for i in range(100): 2227 # verify that random multisets with no repeats are exactly like sets 2228 p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) 2229 q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) 2230 for counterop, setop in [ 2231 (Counter.__sub__, set.__sub__), 2232 (Counter.__or__, set.__or__), 2233 (Counter.__and__, set.__and__), 2234 ]: 2235 counter_result = counterop(p, q) 2236 set_result = setop(set(p.elements()), set(q.elements())) 2237 self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) 2238 2239 def test_inplace_operations(self): 2240 elements = 'abcd' 2241 for i in range(1000): 2242 # test random pairs of multisets 2243 p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2244 p.update(e=1, f=-1, g=0) 2245 q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) 2246 q.update(h=1, i=-1, j=0) 2247 for inplace_op, regular_op in [ 2248 (Counter.__iadd__, Counter.__add__), 2249 (Counter.__isub__, Counter.__sub__), 2250 (Counter.__ior__, Counter.__or__), 2251 (Counter.__iand__, Counter.__and__), 2252 ]: 2253 c = p.copy() 2254 c_id = id(c) 2255 regular_result = regular_op(c, q) 2256 inplace_result = inplace_op(c, q) 2257 self.assertEqual(inplace_result, regular_result) 2258 self.assertEqual(id(inplace_result), c_id) 2259 2260 def test_subtract(self): 2261 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 2262 c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) 2263 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) 2264 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 2265 c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) 2266 self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) 2267 c = Counter('aaabbcd') 2268 c.subtract('aaaabbcce') 2269 self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) 2270 2271 c = Counter() 2272 c.subtract(self=42) 2273 self.assertEqual(list(c.items()), [('self', -42)]) 2274 c = Counter() 2275 c.subtract(iterable=42) 2276 self.assertEqual(list(c.items()), [('iterable', -42)]) 2277 self.assertRaises(TypeError, Counter().subtract, 42) 2278 self.assertRaises(TypeError, Counter().subtract, {}, {}) 2279 self.assertRaises(TypeError, Counter.subtract) 2280 2281 def test_unary(self): 2282 c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) 2283 self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) 2284 self.assertEqual(dict(-c), dict(a=5)) 2285 2286 def test_repr_nonsortable(self): 2287 c = Counter(a=2, b=None) 2288 r = repr(c) 2289 self.assertIn("'a': 2", r) 2290 self.assertIn("'b': None", r) 2291 2292 def test_helper_function(self): 2293 # two paths, one for real dicts and one for other mappings 2294 elems = list('abracadabra') 2295 2296 d = dict() 2297 _count_elements(d, elems) 2298 self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) 2299 2300 m = OrderedDict() 2301 _count_elements(m, elems) 2302 self.assertEqual(m, 2303 OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) 2304 2305 # test fidelity to the pure python version 2306 c = CounterSubclassWithSetItem('abracadabra') 2307 self.assertTrue(c.called) 2308 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) 2309 c = CounterSubclassWithGet('abracadabra') 2310 self.assertTrue(c.called) 2311 self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) 2312 2313 def test_multiset_operations_equivalent_to_set_operations(self): 2314 # When the multiplicities are all zero or one, multiset operations 2315 # are guaranteed to be equivalent to the corresponding operations 2316 # for regular sets. 2317 s = list(product(('a', 'b', 'c'), range(2))) 2318 powerset = chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) 2319 counters = [Counter(dict(groups)) for groups in powerset] 2320 for cp, cq in product(counters, repeat=2): 2321 sp = set(cp.elements()) 2322 sq = set(cq.elements()) 2323 self.assertEqual(set(cp + cq), sp | sq) 2324 self.assertEqual(set(cp - cq), sp - sq) 2325 self.assertEqual(set(cp | cq), sp | sq) 2326 self.assertEqual(set(cp & cq), sp & sq) 2327 self.assertEqual(cp == cq, sp == sq) 2328 self.assertEqual(cp != cq, sp != sq) 2329 self.assertEqual(cp <= cq, sp <= sq) 2330 self.assertEqual(cp >= cq, sp >= sq) 2331 self.assertEqual(cp < cq, sp < sq) 2332 self.assertEqual(cp > cq, sp > sq) 2333 2334 def test_eq(self): 2335 self.assertEqual(Counter(a=3, b=2, c=0), Counter('ababa')) 2336 self.assertNotEqual(Counter(a=3, b=2), Counter('babab')) 2337 2338 def test_le(self): 2339 self.assertTrue(Counter(a=3, b=2, c=0) <= Counter('ababa')) 2340 self.assertFalse(Counter(a=3, b=2) <= Counter('babab')) 2341 2342 def test_lt(self): 2343 self.assertTrue(Counter(a=3, b=1, c=0) < Counter('ababa')) 2344 self.assertFalse(Counter(a=3, b=2, c=0) < Counter('ababa')) 2345 2346 def test_ge(self): 2347 self.assertTrue(Counter(a=2, b=1, c=0) >= Counter('aab')) 2348 self.assertFalse(Counter(a=3, b=2, c=0) >= Counter('aabd')) 2349 2350 def test_gt(self): 2351 self.assertTrue(Counter(a=3, b=2, c=0) > Counter('aab')) 2352 self.assertFalse(Counter(a=2, b=1, c=0) > Counter('aab')) 2353 2354 2355################################################################################ 2356### Run tests 2357################################################################################ 2358 2359def test_main(verbose=None): 2360 NamedTupleDocs = doctest.DocTestSuite(module=collections) 2361 test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, 2362 TestCollectionABCs, TestCounter, TestChainMap, 2363 TestUserObjects, 2364 ] 2365 support.run_unittest(*test_classes) 2366 support.run_doctest(collections, verbose) 2367 2368 2369if __name__ == "__main__": 2370 test_main(verbose=True) 2371