test_collections.py 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. import collections
  2. import copy
  3. import doctest
  4. import keyword
  5. import operator
  6. import pickle
  7. import cPickle
  8. from random import choice, randrange
  9. import re
  10. import string
  11. import sys
  12. from test import test_support
  13. import unittest
  14. from collections import namedtuple, Counter, OrderedDict
  15. from collections import Hashable, Iterable, Iterator
  16. from collections import Sized, Container, Callable
  17. from collections import Set, MutableSet
  18. from collections import Mapping, MutableMapping
  19. from collections import Sequence, MutableSequence
  20. # Silence deprecation warning
  21. sets = test_support.import_module('sets', deprecated=True)
  22. TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests
  23. py273_named_tuple_pickle = '''\
  24. ccopy_reg
  25. _reconstructor
  26. p0
  27. (ctest.test_collections
  28. TestNT
  29. p1
  30. c__builtin__
  31. tuple
  32. p2
  33. (I10
  34. I20
  35. I30
  36. tp3
  37. tp4
  38. Rp5
  39. ccollections
  40. OrderedDict
  41. p6
  42. ((lp7
  43. (lp8
  44. S'x'
  45. p9
  46. aI10
  47. aa(lp10
  48. S'y'
  49. p11
  50. aI20
  51. aa(lp12
  52. S'z'
  53. p13
  54. aI30
  55. aatp14
  56. Rp15
  57. b.
  58. '''
  59. class TestNamedTuple(unittest.TestCase):
  60. def test_factory(self):
  61. Point = namedtuple('Point', 'x y')
  62. self.assertEqual(Point.__name__, 'Point')
  63. self.assertEqual(Point.__slots__, ())
  64. self.assertEqual(Point.__module__, __name__)
  65. self.assertEqual(Point.__getitem__, tuple.__getitem__)
  66. self.assertEqual(Point._fields, ('x', 'y'))
  67. self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char
  68. self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword
  69. self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit
  70. self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
  71. self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
  72. self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
  73. self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
  74. self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
  75. namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
  76. namedtuple('_', 'a b c') # Test leading underscores in a typename
  77. nt = namedtuple('nt', u'the quick brown fox') # check unicode input
  78. self.assertNotIn("u'", repr(nt._fields))
  79. nt = namedtuple('nt', (u'the', u'quick')) # check unicode input
  80. self.assertNotIn("u'", repr(nt._fields))
  81. self.assertRaises(TypeError, Point._make, [11]) # catch too few args
  82. self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args
  83. @unittest.skipIf(sys.flags.optimize >= 2,
  84. "Docstrings are omitted with -O2 and above")
  85. def test_factory_doc_attr(self):
  86. Point = namedtuple('Point', 'x y')
  87. self.assertEqual(Point.__doc__, 'Point(x, y)')
  88. def test_name_fixer(self):
  89. for spec, renamed in [
  90. [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char
  91. [('abc', 'class'), ('abc', '_1')], # field has keyword
  92. [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit
  93. [('abc', '_efg'), ('abc', '_1')], # field with leading underscore
  94. [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field
  95. [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space
  96. ]:
  97. self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed)
  98. def test_instance(self):
  99. Point = namedtuple('Point', 'x y')
  100. p = Point(11, 22)
  101. self.assertEqual(p, Point(x=11, y=22))
  102. self.assertEqual(p, Point(11, y=22))
  103. self.assertEqual(p, Point(y=22, x=11))
  104. self.assertEqual(p, Point(*(11, 22)))
  105. self.assertEqual(p, Point(**dict(x=11, y=22)))
  106. self.assertRaises(TypeError, Point, 1) # too few args
  107. self.assertRaises(TypeError, Point, 1, 2, 3) # too many args
  108. self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument
  109. self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument
  110. self.assertEqual(repr(p), 'Point(x=11, y=22)')
  111. self.assertNotIn('__weakref__', dir(p))
  112. self.assertEqual(p, Point._make([11, 22])) # test _make classmethod
  113. self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
  114. self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
  115. self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
  116. self.assertEqual(vars(p), p._asdict()) # verify that vars() works
  117. try:
  118. p._replace(x=1, error=2)
  119. except ValueError:
  120. pass
  121. else:
  122. self._fail('Did not detect an incorrect fieldname')
  123. # verify that field string can have commas
  124. Point = namedtuple('Point', 'x, y')
  125. p = Point(x=11, y=22)
  126. self.assertEqual(repr(p), 'Point(x=11, y=22)')
  127. # verify that fieldspec can be a non-string sequence
  128. Point = namedtuple('Point', ('x', 'y'))
  129. p = Point(x=11, y=22)
  130. self.assertEqual(repr(p), 'Point(x=11, y=22)')
  131. def test_tupleness(self):
  132. Point = namedtuple('Point', 'x y')
  133. p = Point(11, 22)
  134. self.assertIsInstance(p, tuple)
  135. self.assertEqual(p, (11, 22)) # matches a real tuple
  136. self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple
  137. self.assertEqual(list(p), [11, 22]) # coercable to a list
  138. self.assertEqual(max(p), 22) # iterable
  139. self.assertEqual(max(*p), 22) # star-able
  140. x, y = p
  141. self.assertEqual(p, (x, y)) # unpacks like a tuple
  142. self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple
  143. self.assertRaises(IndexError, p.__getitem__, 3)
  144. self.assertEqual(p.x, x)
  145. self.assertEqual(p.y, y)
  146. self.assertRaises(AttributeError, eval, 'p.z', locals())
  147. def test_odd_sizes(self):
  148. Zero = namedtuple('Zero', '')
  149. self.assertEqual(Zero(), ())
  150. self.assertEqual(Zero._make([]), ())
  151. self.assertEqual(repr(Zero()), 'Zero()')
  152. self.assertEqual(Zero()._asdict(), {})
  153. self.assertEqual(Zero()._fields, ())
  154. Dot = namedtuple('Dot', 'd')
  155. self.assertEqual(Dot(1), (1,))
  156. self.assertEqual(Dot._make([1]), (1,))
  157. self.assertEqual(Dot(1).d, 1)
  158. self.assertEqual(repr(Dot(1)), 'Dot(d=1)')
  159. self.assertEqual(Dot(1)._asdict(), {'d':1})
  160. self.assertEqual(Dot(1)._replace(d=999), (999,))
  161. self.assertEqual(Dot(1)._fields, ('d',))
  162. n = 5000
  163. names = list(set(''.join([choice(string.ascii_letters)
  164. for j in range(10)]) for i in range(n)))
  165. n = len(names)
  166. Big = namedtuple('Big', names)
  167. b = Big(*range(n))
  168. self.assertEqual(b, tuple(range(n)))
  169. self.assertEqual(Big._make(range(n)), tuple(range(n)))
  170. for pos, name in enumerate(names):
  171. self.assertEqual(getattr(b, name), pos)
  172. repr(b) # make sure repr() doesn't blow-up
  173. d = b._asdict()
  174. d_expected = dict(zip(names, range(n)))
  175. self.assertEqual(d, d_expected)
  176. b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)]))
  177. b2_expected = range(n)
  178. b2_expected[1] = 999
  179. b2_expected[-5] = 42
  180. self.assertEqual(b2, tuple(b2_expected))
  181. self.assertEqual(b._fields, tuple(names))
  182. def test_pickle(self):
  183. p = TestNT(x=10, y=20, z=30)
  184. for module in pickle, cPickle:
  185. loads = getattr(module, 'loads')
  186. dumps = getattr(module, 'dumps')
  187. for protocol in -1, 0, 1, 2:
  188. q = loads(dumps(p, protocol))
  189. self.assertEqual(p, q)
  190. self.assertEqual(p._fields, q._fields)
  191. def test_copy(self):
  192. p = TestNT(x=10, y=20, z=30)
  193. for copier in copy.copy, copy.deepcopy:
  194. q = copier(p)
  195. self.assertEqual(p, q)
  196. self.assertEqual(p._fields, q._fields)
  197. def test_name_conflicts(self):
  198. # Some names like "self", "cls", "tuple", "itemgetter", and "property"
  199. # failed when used as field names. Test to make sure these now work.
  200. T = namedtuple('T', 'itemgetter property self cls tuple')
  201. t = T(1, 2, 3, 4, 5)
  202. self.assertEqual(t, (1,2,3,4,5))
  203. newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50)
  204. self.assertEqual(newt, (10,20,30,40,50))
  205. # Broader test of all interesting names in a template
  206. with test_support.captured_stdout() as template:
  207. T = namedtuple('T', 'x', verbose=True)
  208. words = set(re.findall('[A-Za-z]+', template.getvalue()))
  209. words -= set(keyword.kwlist)
  210. T = namedtuple('T', words)
  211. # test __new__
  212. values = tuple(range(len(words)))
  213. t = T(*values)
  214. self.assertEqual(t, values)
  215. t = T(**dict(zip(T._fields, values)))
  216. self.assertEqual(t, values)
  217. # test _make
  218. t = T._make(values)
  219. self.assertEqual(t, values)
  220. # exercise __repr__
  221. repr(t)
  222. # test _asdict
  223. self.assertEqual(t._asdict(), dict(zip(T._fields, values)))
  224. # test _replace
  225. t = T._make(values)
  226. newvalues = tuple(v*10 for v in values)
  227. newt = t._replace(**dict(zip(T._fields, newvalues)))
  228. self.assertEqual(newt, newvalues)
  229. # test _fields
  230. self.assertEqual(T._fields, tuple(words))
  231. # test __getnewargs__
  232. self.assertEqual(t.__getnewargs__(), values)
  233. def test_pickling_bug_18015(self):
  234. # http://bugs.python.org/issue18015
  235. pt = pickle.loads(py273_named_tuple_pickle)
  236. self.assertEqual(pt.x, 10)
  237. class ABCTestCase(unittest.TestCase):
  238. def validate_abstract_methods(self, abc, *names):
  239. methodstubs = dict.fromkeys(names, lambda s, *args: 0)
  240. # everything should work will all required methods are present
  241. C = type('C', (abc,), methodstubs)
  242. C()
  243. # instantiation should fail if a required method is missing
  244. for name in names:
  245. stubs = methodstubs.copy()
  246. del stubs[name]
  247. C = type('C', (abc,), stubs)
  248. self.assertRaises(TypeError, C, name)
  249. def validate_isinstance(self, abc, name):
  250. stub = lambda s, *args: 0
  251. # new-style class
  252. C = type('C', (object,), {name: stub})
  253. self.assertIsInstance(C(), abc)
  254. self.assertTrue(issubclass(C, abc))
  255. # old-style class
  256. class C: pass
  257. setattr(C, name, stub)
  258. self.assertIsInstance(C(), abc)
  259. self.assertTrue(issubclass(C, abc))
  260. # new-style class
  261. C = type('C', (object,), {'__hash__': None})
  262. self.assertNotIsInstance(C(), abc)
  263. self.assertFalse(issubclass(C, abc))
  264. # old-style class
  265. class C: pass
  266. self.assertNotIsInstance(C(), abc)
  267. self.assertFalse(issubclass(C, abc))
  268. def validate_comparison(self, instance):
  269. ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub']
  270. operators = {}
  271. for op in ops:
  272. name = '__' + op + '__'
  273. operators[name] = getattr(operator, name)
  274. class Other:
  275. def __init__(self):
  276. self.right_side = False
  277. def __eq__(self, other):
  278. self.right_side = True
  279. return True
  280. __lt__ = __eq__
  281. __gt__ = __eq__
  282. __le__ = __eq__
  283. __ge__ = __eq__
  284. __ne__ = __eq__
  285. __ror__ = __eq__
  286. __rand__ = __eq__
  287. __rxor__ = __eq__
  288. __rsub__ = __eq__
  289. for name, op in operators.items():
  290. if not hasattr(instance, name):
  291. continue
  292. other = Other()
  293. op(instance, other)
  294. self.assertTrue(other.right_side,'Right side not called for %s.%s'
  295. % (type(instance), name))
  296. class TestOneTrickPonyABCs(ABCTestCase):
  297. def test_Hashable(self):
  298. # Check some non-hashables
  299. non_samples = [list(), set(), dict()]
  300. for x in non_samples:
  301. self.assertNotIsInstance(x, Hashable)
  302. self.assertFalse(issubclass(type(x), Hashable), repr(type(x)))
  303. # Check some hashables
  304. samples = [None,
  305. int(), float(), complex(),
  306. str(),
  307. tuple(), frozenset(),
  308. int, list, object, type,
  309. ]
  310. for x in samples:
  311. self.assertIsInstance(x, Hashable)
  312. self.assertTrue(issubclass(type(x), Hashable), repr(type(x)))
  313. self.assertRaises(TypeError, Hashable)
  314. # Check direct subclassing
  315. class H(Hashable):
  316. def __hash__(self):
  317. return super(H, self).__hash__()
  318. __eq__ = Hashable.__eq__ # Silence Py3k warning
  319. self.assertEqual(hash(H()), 0)
  320. self.assertFalse(issubclass(int, H))
  321. self.validate_abstract_methods(Hashable, '__hash__')
  322. self.validate_isinstance(Hashable, '__hash__')
  323. def test_Iterable(self):
  324. # Check some non-iterables
  325. non_samples = [None, 42, 3.14, 1j]
  326. for x in non_samples:
  327. self.assertNotIsInstance(x, Iterable)
  328. self.assertFalse(issubclass(type(x), Iterable), repr(type(x)))
  329. # Check some iterables
  330. samples = [str(),
  331. tuple(), list(), set(), frozenset(), dict(),
  332. dict().keys(), dict().items(), dict().values(),
  333. (lambda: (yield))(),
  334. (x for x in []),
  335. ]
  336. for x in samples:
  337. self.assertIsInstance(x, Iterable)
  338. self.assertTrue(issubclass(type(x), Iterable), repr(type(x)))
  339. # Check direct subclassing
  340. class I(Iterable):
  341. def __iter__(self):
  342. return super(I, self).__iter__()
  343. self.assertEqual(list(I()), [])
  344. self.assertFalse(issubclass(str, I))
  345. self.validate_abstract_methods(Iterable, '__iter__')
  346. self.validate_isinstance(Iterable, '__iter__')
  347. def test_Iterator(self):
  348. non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [],
  349. {}, set()]
  350. for x in non_samples:
  351. self.assertNotIsInstance(x, Iterator)
  352. self.assertFalse(issubclass(type(x), Iterator), repr(type(x)))
  353. samples = [iter(str()),
  354. iter(tuple()), iter(list()), iter(dict()),
  355. iter(set()), iter(frozenset()),
  356. iter(dict().keys()), iter(dict().items()),
  357. iter(dict().values()),
  358. (lambda: (yield))(),
  359. (x for x in []),
  360. ]
  361. for x in samples:
  362. self.assertIsInstance(x, Iterator)
  363. self.assertTrue(issubclass(type(x), Iterator), repr(type(x)))
  364. self.validate_abstract_methods(Iterator, 'next', '__iter__')
  365. # Issue 10565
  366. class NextOnly:
  367. def __next__(self):
  368. yield 1
  369. raise StopIteration
  370. self.assertNotIsInstance(NextOnly(), Iterator)
  371. class NextOnlyNew(object):
  372. def __next__(self):
  373. yield 1
  374. raise StopIteration
  375. self.assertNotIsInstance(NextOnlyNew(), Iterator)
  376. def test_Sized(self):
  377. non_samples = [None, 42, 3.14, 1j,
  378. (lambda: (yield))(),
  379. (x for x in []),
  380. ]
  381. for x in non_samples:
  382. self.assertNotIsInstance(x, Sized)
  383. self.assertFalse(issubclass(type(x), Sized), repr(type(x)))
  384. samples = [str(),
  385. tuple(), list(), set(), frozenset(), dict(),
  386. dict().keys(), dict().items(), dict().values(),
  387. ]
  388. for x in samples:
  389. self.assertIsInstance(x, Sized)
  390. self.assertTrue(issubclass(type(x), Sized), repr(type(x)))
  391. self.validate_abstract_methods(Sized, '__len__')
  392. self.validate_isinstance(Sized, '__len__')
  393. def test_Container(self):
  394. non_samples = [None, 42, 3.14, 1j,
  395. (lambda: (yield))(),
  396. (x for x in []),
  397. ]
  398. for x in non_samples:
  399. self.assertNotIsInstance(x, Container)
  400. self.assertFalse(issubclass(type(x), Container), repr(type(x)))
  401. samples = [str(),
  402. tuple(), list(), set(), frozenset(), dict(),
  403. dict().keys(), dict().items(),
  404. ]
  405. for x in samples:
  406. self.assertIsInstance(x, Container)
  407. self.assertTrue(issubclass(type(x), Container), repr(type(x)))
  408. self.validate_abstract_methods(Container, '__contains__')
  409. self.validate_isinstance(Container, '__contains__')
  410. def test_Callable(self):
  411. non_samples = [None, 42, 3.14, 1j,
  412. "", "".encode('ascii'), (), [], {}, set(),
  413. (lambda: (yield))(),
  414. (x for x in []),
  415. ]
  416. for x in non_samples:
  417. self.assertNotIsInstance(x, Callable)
  418. self.assertFalse(issubclass(type(x), Callable), repr(type(x)))
  419. samples = [lambda: None,
  420. type, int, object,
  421. len,
  422. list.append, [].append,
  423. ]
  424. for x in samples:
  425. self.assertIsInstance(x, Callable)
  426. self.assertTrue(issubclass(type(x), Callable), repr(type(x)))
  427. self.validate_abstract_methods(Callable, '__call__')
  428. self.validate_isinstance(Callable, '__call__')
  429. def test_direct_subclassing(self):
  430. for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
  431. class C(B):
  432. pass
  433. self.assertTrue(issubclass(C, B))
  434. self.assertFalse(issubclass(int, C))
  435. def test_registration(self):
  436. for B in Hashable, Iterable, Iterator, Sized, Container, Callable:
  437. class C:
  438. __metaclass__ = type
  439. __hash__ = None # Make sure it isn't hashable by default
  440. self.assertFalse(issubclass(C, B), B.__name__)
  441. B.register(C)
  442. self.assertTrue(issubclass(C, B))
  443. class WithSet(MutableSet):
  444. def __init__(self, it=()):
  445. self.data = set(it)
  446. def __len__(self):
  447. return len(self.data)
  448. def __iter__(self):
  449. return iter(self.data)
  450. def __contains__(self, item):
  451. return item in self.data
  452. def add(self, item):
  453. self.data.add(item)
  454. def discard(self, item):
  455. self.data.discard(item)
  456. class TestCollectionABCs(ABCTestCase):
  457. # XXX For now, we only test some virtual inheritance properties.
  458. # We should also test the proper behavior of the collection ABCs
  459. # as real base classes or mix-in classes.
  460. def test_Set(self):
  461. for sample in [set, frozenset]:
  462. self.assertIsInstance(sample(), Set)
  463. self.assertTrue(issubclass(sample, Set))
  464. self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__')
  465. class MySet(Set):
  466. def __contains__(self, x):
  467. return False
  468. def __len__(self):
  469. return 0
  470. def __iter__(self):
  471. return iter([])
  472. self.validate_comparison(MySet())
  473. def test_hash_Set(self):
  474. class OneTwoThreeSet(Set):
  475. def __init__(self):
  476. self.contents = [1, 2, 3]
  477. def __contains__(self, x):
  478. return x in self.contents
  479. def __len__(self):
  480. return len(self.contents)
  481. def __iter__(self):
  482. return iter(self.contents)
  483. def __hash__(self):
  484. return self._hash()
  485. a, b = OneTwoThreeSet(), OneTwoThreeSet()
  486. self.assertTrue(hash(a) == hash(b))
  487. def test_MutableSet(self):
  488. self.assertIsInstance(set(), MutableSet)
  489. self.assertTrue(issubclass(set, MutableSet))
  490. self.assertNotIsInstance(frozenset(), MutableSet)
  491. self.assertFalse(issubclass(frozenset, MutableSet))
  492. self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__',
  493. 'add', 'discard')
  494. def test_issue_5647(self):
  495. # MutableSet.__iand__ mutated the set during iteration
  496. s = WithSet('abcd')
  497. s &= WithSet('cdef') # This used to fail
  498. self.assertEqual(set(s), set('cd'))
  499. def test_issue_4920(self):
  500. # MutableSet.pop() method did not work
  501. class MySet(MutableSet):
  502. __slots__=['__s']
  503. def __init__(self,items=None):
  504. if items is None:
  505. items=[]
  506. self.__s=set(items)
  507. def __contains__(self,v):
  508. return v in self.__s
  509. def __iter__(self):
  510. return iter(self.__s)
  511. def __len__(self):
  512. return len(self.__s)
  513. def add(self,v):
  514. result=v not in self.__s
  515. self.__s.add(v)
  516. return result
  517. def discard(self,v):
  518. result=v in self.__s
  519. self.__s.discard(v)
  520. return result
  521. def __repr__(self):
  522. return "MySet(%s)" % repr(list(self))
  523. s = MySet([5,43,2,1])
  524. self.assertEqual(s.pop(), 1)
  525. def test_issue8750(self):
  526. empty = WithSet()
  527. full = WithSet(range(10))
  528. s = WithSet(full)
  529. s -= s
  530. self.assertEqual(s, empty)
  531. s = WithSet(full)
  532. s ^= s
  533. self.assertEqual(s, empty)
  534. s = WithSet(full)
  535. s &= s
  536. self.assertEqual(s, full)
  537. s |= s
  538. self.assertEqual(s, full)
  539. def test_issue16373(self):
  540. # Recursion error comparing comparable and noncomparable
  541. # Set instances
  542. class MyComparableSet(Set):
  543. def __contains__(self, x):
  544. return False
  545. def __len__(self):
  546. return 0
  547. def __iter__(self):
  548. return iter([])
  549. class MyNonComparableSet(Set):
  550. def __contains__(self, x):
  551. return False
  552. def __len__(self):
  553. return 0
  554. def __iter__(self):
  555. return iter([])
  556. def __le__(self, x):
  557. return NotImplemented
  558. def __lt__(self, x):
  559. return NotImplemented
  560. cs = MyComparableSet()
  561. ncs = MyNonComparableSet()
  562. # Run all the variants to make sure they don't mutually recurse
  563. ncs < cs
  564. ncs <= cs
  565. ncs > cs
  566. ncs >= cs
  567. cs < ncs
  568. cs <= ncs
  569. cs > ncs
  570. cs >= ncs
  571. def assertSameSet(self, s1, s2):
  572. # coerce both to a real set then check equality
  573. self.assertEqual(set(s1), set(s2))
  574. def test_Set_interoperability_with_real_sets(self):
  575. # Issue: 8743
  576. class ListSet(Set):
  577. def __init__(self, elements=()):
  578. self.data = []
  579. for elem in elements:
  580. if elem not in self.data:
  581. self.data.append(elem)
  582. def __contains__(self, elem):
  583. return elem in self.data
  584. def __iter__(self):
  585. return iter(self.data)
  586. def __len__(self):
  587. return len(self.data)
  588. def __repr__(self):
  589. return 'Set({!r})'.format(self.data)
  590. r1 = set('abc')
  591. r2 = set('bcd')
  592. r3 = set('abcde')
  593. f1 = ListSet('abc')
  594. f2 = ListSet('bcd')
  595. f3 = ListSet('abcde')
  596. l1 = list('abccba')
  597. l2 = list('bcddcb')
  598. l3 = list('abcdeedcba')
  599. p1 = sets.Set('abc')
  600. p2 = sets.Set('bcd')
  601. p3 = sets.Set('abcde')
  602. target = r1 & r2
  603. self.assertSameSet(f1 & f2, target)
  604. self.assertSameSet(f1 & r2, target)
  605. self.assertSameSet(r2 & f1, target)
  606. self.assertSameSet(f1 & p2, target)
  607. self.assertSameSet(p2 & f1, target)
  608. self.assertSameSet(f1 & l2, target)
  609. target = r1 | r2
  610. self.assertSameSet(f1 | f2, target)
  611. self.assertSameSet(f1 | r2, target)
  612. self.assertSameSet(r2 | f1, target)
  613. self.assertSameSet(f1 | p2, target)
  614. self.assertSameSet(p2 | f1, target)
  615. self.assertSameSet(f1 | l2, target)
  616. fwd_target = r1 - r2
  617. rev_target = r2 - r1
  618. self.assertSameSet(f1 - f2, fwd_target)
  619. self.assertSameSet(f2 - f1, rev_target)
  620. self.assertSameSet(f1 - r2, fwd_target)
  621. self.assertSameSet(f2 - r1, rev_target)
  622. self.assertSameSet(r1 - f2, fwd_target)
  623. self.assertSameSet(r2 - f1, rev_target)
  624. self.assertSameSet(f1 - p2, fwd_target)
  625. self.assertSameSet(f2 - p1, rev_target)
  626. self.assertSameSet(p1 - f2, fwd_target)
  627. self.assertSameSet(p2 - f1, rev_target)
  628. self.assertSameSet(f1 - l2, fwd_target)
  629. self.assertSameSet(f2 - l1, rev_target)
  630. target = r1 ^ r2
  631. self.assertSameSet(f1 ^ f2, target)
  632. self.assertSameSet(f1 ^ r2, target)
  633. self.assertSameSet(r2 ^ f1, target)
  634. self.assertSameSet(f1 ^ p2, target)
  635. self.assertSameSet(p2 ^ f1, target)
  636. self.assertSameSet(f1 ^ l2, target)
  637. # proper subset
  638. self.assertTrue(f1 < f3)
  639. self.assertFalse(f1 < f1)
  640. self.assertFalse(f1 < f2)
  641. self.assertTrue(r1 < f3)
  642. self.assertFalse(r1 < f1)
  643. self.assertFalse(r1 < f2)
  644. self.assertTrue(r1 < r3)
  645. self.assertFalse(r1 < r1)
  646. self.assertFalse(r1 < r2)
  647. with test_support.check_py3k_warnings():
  648. # python 2 only, cross-type compares will succeed
  649. f1 < l3
  650. f1 < l1
  651. f1 < l2
  652. # any subset
  653. self.assertTrue(f1 <= f3)
  654. self.assertTrue(f1 <= f1)
  655. self.assertFalse(f1 <= f2)
  656. self.assertTrue(r1 <= f3)
  657. self.assertTrue(r1 <= f1)
  658. self.assertFalse(r1 <= f2)
  659. self.assertTrue(r1 <= r3)
  660. self.assertTrue(r1 <= r1)
  661. self.assertFalse(r1 <= r2)
  662. with test_support.check_py3k_warnings():
  663. # python 2 only, cross-type compares will succeed
  664. f1 <= l3
  665. f1 <= l1
  666. f1 <= l2
  667. # proper superset
  668. self.assertTrue(f3 > f1)
  669. self.assertFalse(f1 > f1)
  670. self.assertFalse(f2 > f1)
  671. self.assertTrue(r3 > r1)
  672. self.assertFalse(f1 > r1)
  673. self.assertFalse(f2 > r1)
  674. self.assertTrue(r3 > r1)
  675. self.assertFalse(r1 > r1)
  676. self.assertFalse(r2 > r1)
  677. with test_support.check_py3k_warnings():
  678. # python 2 only, cross-type compares will succeed
  679. f1 > l3
  680. f1 > l1
  681. f1 > l2
  682. # any superset
  683. self.assertTrue(f3 >= f1)
  684. self.assertTrue(f1 >= f1)
  685. self.assertFalse(f2 >= f1)
  686. self.assertTrue(r3 >= r1)
  687. self.assertTrue(f1 >= r1)
  688. self.assertFalse(f2 >= r1)
  689. self.assertTrue(r3 >= r1)
  690. self.assertTrue(r1 >= r1)
  691. self.assertFalse(r2 >= r1)
  692. with test_support.check_py3k_warnings():
  693. # python 2 only, cross-type compares will succeed
  694. f1 >= l3
  695. f1 >=l1
  696. f1 >= l2
  697. # equality
  698. self.assertTrue(f1 == f1)
  699. self.assertTrue(r1 == f1)
  700. self.assertTrue(f1 == r1)
  701. self.assertFalse(f1 == f3)
  702. self.assertFalse(r1 == f3)
  703. self.assertFalse(f1 == r3)
  704. # python 2 only, cross-type compares will succeed
  705. f1 == l3
  706. f1 == l1
  707. f1 == l2
  708. # inequality
  709. self.assertFalse(f1 != f1)
  710. self.assertFalse(r1 != f1)
  711. self.assertFalse(f1 != r1)
  712. self.assertTrue(f1 != f3)
  713. self.assertTrue(r1 != f3)
  714. self.assertTrue(f1 != r3)
  715. # python 2 only, cross-type compares will succeed
  716. f1 != l3
  717. f1 != l1
  718. f1 != l2
  719. def test_Mapping(self):
  720. for sample in [dict]:
  721. self.assertIsInstance(sample(), Mapping)
  722. self.assertTrue(issubclass(sample, Mapping))
  723. self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__',
  724. '__getitem__')
  725. class MyMapping(Mapping):
  726. def __len__(self):
  727. return 0
  728. def __getitem__(self, i):
  729. raise IndexError
  730. def __iter__(self):
  731. return iter(())
  732. self.validate_comparison(MyMapping())
  733. def test_MutableMapping(self):
  734. for sample in [dict]:
  735. self.assertIsInstance(sample(), MutableMapping)
  736. self.assertTrue(issubclass(sample, MutableMapping))
  737. self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__',
  738. '__getitem__', '__setitem__', '__delitem__')
  739. def test_Sequence(self):
  740. for sample in [tuple, list, str]:
  741. self.assertIsInstance(sample(), Sequence)
  742. self.assertTrue(issubclass(sample, Sequence))
  743. self.assertTrue(issubclass(basestring, Sequence))
  744. self.assertIsInstance(range(10), Sequence)
  745. self.assertTrue(issubclass(xrange, Sequence))
  746. self.assertTrue(issubclass(str, Sequence))
  747. self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
  748. '__getitem__')
  749. def test_MutableSequence(self):
  750. for sample in [tuple, str]:
  751. self.assertNotIsInstance(sample(), MutableSequence)
  752. self.assertFalse(issubclass(sample, MutableSequence))
  753. for sample in [list]:
  754. self.assertIsInstance(sample(), MutableSequence)
  755. self.assertTrue(issubclass(sample, MutableSequence))
  756. self.assertFalse(issubclass(basestring, MutableSequence))
  757. self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__',
  758. '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert')
  759. class TestCounter(unittest.TestCase):
  760. def test_basics(self):
  761. c = Counter('abcaba')
  762. self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1}))
  763. self.assertEqual(c, Counter(a=3, b=2, c=1))
  764. self.assertIsInstance(c, dict)
  765. self.assertIsInstance(c, Mapping)
  766. self.assertTrue(issubclass(Counter, dict))
  767. self.assertTrue(issubclass(Counter, Mapping))
  768. self.assertEqual(len(c), 3)
  769. self.assertEqual(sum(c.values()), 6)
  770. self.assertEqual(sorted(c.values()), [1, 2, 3])
  771. self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
  772. self.assertEqual(sorted(c), ['a', 'b', 'c'])
  773. self.assertEqual(sorted(c.items()),
  774. [('a', 3), ('b', 2), ('c', 1)])
  775. self.assertEqual(c['b'], 2)
  776. self.assertEqual(c['z'], 0)
  777. with test_support.check_py3k_warnings():
  778. self.assertEqual(c.has_key('c'), True)
  779. self.assertEqual(c.has_key('z'), False)
  780. self.assertEqual(c.__contains__('c'), True)
  781. self.assertEqual(c.__contains__('z'), False)
  782. self.assertEqual(c.get('b', 10), 2)
  783. self.assertEqual(c.get('z', 10), 10)
  784. self.assertEqual(c, dict(a=3, b=2, c=1))
  785. self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
  786. self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
  787. for i in range(5):
  788. self.assertEqual(c.most_common(i),
  789. [('a', 3), ('b', 2), ('c', 1)][:i])
  790. self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
  791. c['a'] += 1 # increment an existing value
  792. c['b'] -= 2 # sub existing value to zero
  793. del c['c'] # remove an entry
  794. del c['c'] # make sure that del doesn't raise KeyError
  795. c['d'] -= 2 # sub from a missing value
  796. c['e'] = -5 # directly assign a missing value
  797. c['f'] += 4 # add to a missing value
  798. self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
  799. self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
  800. self.assertEqual(c.pop('f'), 4)
  801. self.assertNotIn('f', c)
  802. for i in range(3):
  803. elem, cnt = c.popitem()
  804. self.assertNotIn(elem, c)
  805. c.clear()
  806. self.assertEqual(c, {})
  807. self.assertEqual(repr(c), 'Counter()')
  808. self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
  809. self.assertRaises(TypeError, hash, c)
  810. c.update(dict(a=5, b=3))
  811. c.update(c=1)
  812. c.update(Counter('a' * 50 + 'b' * 30))
  813. c.update() # test case with no args
  814. c.__init__('a' * 500 + 'b' * 300)
  815. c.__init__('cdc')
  816. c.__init__()
  817. self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
  818. self.assertEqual(c.setdefault('d', 5), 1)
  819. self.assertEqual(c['d'], 1)
  820. self.assertEqual(c.setdefault('e', 5), 5)
  821. self.assertEqual(c['e'], 5)
  822. def test_init(self):
  823. self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
  824. self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)])
  825. self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)])
  826. self.assertRaises(TypeError, Counter, 42)
  827. self.assertRaises(TypeError, Counter, (), ())
  828. self.assertRaises(TypeError, Counter.__init__)
  829. def test_update(self):
  830. c = Counter()
  831. c.update(self=42)
  832. self.assertEqual(list(c.items()), [('self', 42)])
  833. c = Counter()
  834. c.update(iterable=42)
  835. self.assertEqual(list(c.items()), [('iterable', 42)])
  836. c = Counter()
  837. c.update(iterable=None)
  838. self.assertEqual(list(c.items()), [('iterable', None)])
  839. self.assertRaises(TypeError, Counter().update, 42)
  840. self.assertRaises(TypeError, Counter().update, {}, {})
  841. self.assertRaises(TypeError, Counter.update)
  842. def test_copying(self):
  843. # Check that counters are copyable, deepcopyable, picklable, and
  844. #have a repr/eval round-trip
  845. words = Counter('which witch had which witches wrist watch'.split())
  846. update_test = Counter()
  847. update_test.update(words)
  848. for i, dup in enumerate([
  849. words.copy(),
  850. copy.copy(words),
  851. copy.deepcopy(words),
  852. pickle.loads(pickle.dumps(words, 0)),
  853. pickle.loads(pickle.dumps(words, 1)),
  854. pickle.loads(pickle.dumps(words, 2)),
  855. pickle.loads(pickle.dumps(words, -1)),
  856. cPickle.loads(cPickle.dumps(words, 0)),
  857. cPickle.loads(cPickle.dumps(words, 1)),
  858. cPickle.loads(cPickle.dumps(words, 2)),
  859. cPickle.loads(cPickle.dumps(words, -1)),
  860. eval(repr(words)),
  861. update_test,
  862. Counter(words),
  863. ]):
  864. msg = (i, dup, words)
  865. self.assertTrue(dup is not words)
  866. self.assertEqual(dup, words)
  867. self.assertEqual(len(dup), len(words))
  868. self.assertEqual(type(dup), type(words))
  869. def test_copy_subclass(self):
  870. class MyCounter(Counter):
  871. pass
  872. c = MyCounter('slartibartfast')
  873. d = c.copy()
  874. self.assertEqual(d, c)
  875. self.assertEqual(len(d), len(c))
  876. self.assertEqual(type(d), type(c))
  877. def test_conversions(self):
  878. # Convert to: set, list, dict
  879. s = 'she sells sea shells by the sea shore'
  880. self.assertEqual(sorted(Counter(s).elements()), sorted(s))
  881. self.assertEqual(sorted(Counter(s)), sorted(set(s)))
  882. self.assertEqual(dict(Counter(s)), dict(Counter(s).items()))
  883. self.assertEqual(set(Counter(s)), set(s))
  884. def test_invariant_for_the_in_operator(self):
  885. c = Counter(a=10, b=-2, c=0)
  886. for elem in c:
  887. self.assertTrue(elem in c)
  888. self.assertIn(elem, c)
  889. def test_multiset_operations(self):
  890. # Verify that adding a zero counter will strip zeros and negatives
  891. c = Counter(a=10, b=-2, c=0) + Counter()
  892. self.assertEqual(dict(c), dict(a=10))
  893. elements = 'abcd'
  894. for i in range(1000):
  895. # test random pairs of multisets
  896. p = Counter(dict((elem, randrange(-2,4)) for elem in elements))
  897. p.update(e=1, f=-1, g=0)
  898. q = Counter(dict((elem, randrange(-2,4)) for elem in elements))
  899. q.update(h=1, i=-1, j=0)
  900. for counterop, numberop in [
  901. (Counter.__add__, lambda x, y: max(0, x+y)),
  902. (Counter.__sub__, lambda x, y: max(0, x-y)),
  903. (Counter.__or__, lambda x, y: max(0,x,y)),
  904. (Counter.__and__, lambda x, y: max(0, min(x,y))),
  905. ]:
  906. result = counterop(p, q)
  907. for x in elements:
  908. self.assertEqual(numberop(p[x], q[x]), result[x],
  909. (counterop, x, p, q))
  910. # verify that results exclude non-positive counts
  911. self.assertTrue(x>0 for x in result.values())
  912. elements = 'abcdef'
  913. for i in range(100):
  914. # verify that random multisets with no repeats are exactly like sets
  915. p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
  916. q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
  917. for counterop, setop in [
  918. (Counter.__sub__, set.__sub__),
  919. (Counter.__or__, set.__or__),
  920. (Counter.__and__, set.__and__),
  921. ]:
  922. counter_result = counterop(p, q)
  923. set_result = setop(set(p.elements()), set(q.elements()))
  924. self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
  925. def test_subtract(self):
  926. c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
  927. c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)
  928. self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
  929. c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
  930. c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50))
  931. self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50))
  932. c = Counter('aaabbcd')
  933. c.subtract('aaaabbcce')
  934. self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
  935. c = Counter()
  936. c.subtract(self=42)
  937. self.assertEqual(list(c.items()), [('self', -42)])
  938. c = Counter()
  939. c.subtract(iterable=42)
  940. self.assertEqual(list(c.items()), [('iterable', -42)])
  941. self.assertRaises(TypeError, Counter().subtract, 42)
  942. self.assertRaises(TypeError, Counter().subtract, {}, {})
  943. self.assertRaises(TypeError, Counter.subtract)
  944. def test_main(verbose=None):
  945. NamedTupleDocs = doctest.DocTestSuite(module=collections)
  946. test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
  947. TestCollectionABCs, TestCounter]
  948. test_support.run_unittest(*test_classes)
  949. test_support.run_doctest(collections, verbose)
  950. if __name__ == "__main__":
  951. test_main(verbose=True)