test_set.py 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125
  1. import unittest
  2. from test import support
  3. from test.support import warnings_helper
  4. import gc
  5. import weakref
  6. import operator
  7. import copy
  8. import pickle
  9. from random import randrange, shuffle
  10. import warnings
  11. import collections
  12. import collections.abc
  13. import itertools
  14. class PassThru(Exception):
  15. pass
  16. def check_pass_thru():
  17. raise PassThru
  18. yield 1
  19. class BadCmp:
  20. def __hash__(self):
  21. return 1
  22. def __eq__(self, other):
  23. raise RuntimeError
  24. class ReprWrapper:
  25. 'Used to test self-referential repr() calls'
  26. def __repr__(self):
  27. return repr(self.value)
  28. class HashCountingInt(int):
  29. 'int-like object that counts the number of times __hash__ is called'
  30. def __init__(self, *args):
  31. self.hash_count = 0
  32. def __hash__(self):
  33. self.hash_count += 1
  34. return int.__hash__(self)
  35. class TestJointOps:
  36. # Tests common to both set and frozenset
  37. def setUp(self):
  38. self.word = word = 'simsalabim'
  39. self.otherword = 'madagascar'
  40. self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  41. self.s = self.thetype(word)
  42. self.d = dict.fromkeys(word)
  43. def test_new_or_init(self):
  44. self.assertRaises(TypeError, self.thetype, [], 2)
  45. self.assertRaises(TypeError, set().__init__, a=1)
  46. def test_uniquification(self):
  47. actual = sorted(self.s)
  48. expected = sorted(self.d)
  49. self.assertEqual(actual, expected)
  50. self.assertRaises(PassThru, self.thetype, check_pass_thru())
  51. self.assertRaises(TypeError, self.thetype, [[]])
  52. def test_len(self):
  53. self.assertEqual(len(self.s), len(self.d))
  54. def test_contains(self):
  55. for c in self.letters:
  56. self.assertEqual(c in self.s, c in self.d)
  57. self.assertRaises(TypeError, self.s.__contains__, [[]])
  58. s = self.thetype([frozenset(self.letters)])
  59. self.assertIn(self.thetype(self.letters), s)
  60. def test_union(self):
  61. u = self.s.union(self.otherword)
  62. for c in self.letters:
  63. self.assertEqual(c in u, c in self.d or c in self.otherword)
  64. self.assertEqual(self.s, self.thetype(self.word))
  65. self.assertEqual(type(u), self.basetype)
  66. self.assertRaises(PassThru, self.s.union, check_pass_thru())
  67. self.assertRaises(TypeError, self.s.union, [[]])
  68. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  69. self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd'))
  70. self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg'))
  71. self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc'))
  72. self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef'))
  73. self.assertEqual(self.thetype('abcba').union(C('ef'), C('fg')), set('abcefg'))
  74. # Issue #6573
  75. x = self.thetype()
  76. self.assertEqual(x.union(set([1]), x, set([2])), self.thetype([1, 2]))
  77. def test_or(self):
  78. i = self.s.union(self.otherword)
  79. self.assertEqual(self.s | set(self.otherword), i)
  80. self.assertEqual(self.s | frozenset(self.otherword), i)
  81. try:
  82. self.s | self.otherword
  83. except TypeError:
  84. pass
  85. else:
  86. self.fail("s|t did not screen-out general iterables")
  87. def test_intersection(self):
  88. i = self.s.intersection(self.otherword)
  89. for c in self.letters:
  90. self.assertEqual(c in i, c in self.d and c in self.otherword)
  91. self.assertEqual(self.s, self.thetype(self.word))
  92. self.assertEqual(type(i), self.basetype)
  93. self.assertRaises(PassThru, self.s.intersection, check_pass_thru())
  94. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  95. self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc'))
  96. self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
  97. self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
  98. self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
  99. self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
  100. s = self.thetype('abcba')
  101. z = s.intersection()
  102. if self.thetype == frozenset():
  103. self.assertEqual(id(s), id(z))
  104. else:
  105. self.assertNotEqual(id(s), id(z))
  106. def test_isdisjoint(self):
  107. def f(s1, s2):
  108. 'Pure python equivalent of isdisjoint()'
  109. return not set(s1).intersection(s2)
  110. for larg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
  111. s1 = self.thetype(larg)
  112. for rarg in '', 'a', 'ab', 'abc', 'ababac', 'cdc', 'cc', 'efgfe', 'ccb', 'ef':
  113. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  114. s2 = C(rarg)
  115. actual = s1.isdisjoint(s2)
  116. expected = f(s1, s2)
  117. self.assertEqual(actual, expected)
  118. self.assertTrue(actual is True or actual is False)
  119. def test_and(self):
  120. i = self.s.intersection(self.otherword)
  121. self.assertEqual(self.s & set(self.otherword), i)
  122. self.assertEqual(self.s & frozenset(self.otherword), i)
  123. try:
  124. self.s & self.otherword
  125. except TypeError:
  126. pass
  127. else:
  128. self.fail("s&t did not screen-out general iterables")
  129. def test_difference(self):
  130. i = self.s.difference(self.otherword)
  131. for c in self.letters:
  132. self.assertEqual(c in i, c in self.d and c not in self.otherword)
  133. self.assertEqual(self.s, self.thetype(self.word))
  134. self.assertEqual(type(i), self.basetype)
  135. self.assertRaises(PassThru, self.s.difference, check_pass_thru())
  136. self.assertRaises(TypeError, self.s.difference, [[]])
  137. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  138. self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab'))
  139. self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc'))
  140. self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a'))
  141. self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc'))
  142. self.assertEqual(self.thetype('abcba').difference(), set('abc'))
  143. self.assertEqual(self.thetype('abcba').difference(C('a'), C('b')), set('c'))
  144. def test_sub(self):
  145. i = self.s.difference(self.otherword)
  146. self.assertEqual(self.s - set(self.otherword), i)
  147. self.assertEqual(self.s - frozenset(self.otherword), i)
  148. try:
  149. self.s - self.otherword
  150. except TypeError:
  151. pass
  152. else:
  153. self.fail("s-t did not screen-out general iterables")
  154. def test_symmetric_difference(self):
  155. i = self.s.symmetric_difference(self.otherword)
  156. for c in self.letters:
  157. self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
  158. self.assertEqual(self.s, self.thetype(self.word))
  159. self.assertEqual(type(i), self.basetype)
  160. self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
  161. self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
  162. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  163. self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
  164. self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
  165. self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
  166. self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef'))
  167. def test_xor(self):
  168. i = self.s.symmetric_difference(self.otherword)
  169. self.assertEqual(self.s ^ set(self.otherword), i)
  170. self.assertEqual(self.s ^ frozenset(self.otherword), i)
  171. try:
  172. self.s ^ self.otherword
  173. except TypeError:
  174. pass
  175. else:
  176. self.fail("s^t did not screen-out general iterables")
  177. def test_equality(self):
  178. self.assertEqual(self.s, set(self.word))
  179. self.assertEqual(self.s, frozenset(self.word))
  180. self.assertEqual(self.s == self.word, False)
  181. self.assertNotEqual(self.s, set(self.otherword))
  182. self.assertNotEqual(self.s, frozenset(self.otherword))
  183. self.assertEqual(self.s != self.word, True)
  184. def test_setOfFrozensets(self):
  185. t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba'])
  186. s = self.thetype(t)
  187. self.assertEqual(len(s), 3)
  188. def test_sub_and_super(self):
  189. p, q, r = map(self.thetype, ['ab', 'abcde', 'def'])
  190. self.assertTrue(p < q)
  191. self.assertTrue(p <= q)
  192. self.assertTrue(q <= q)
  193. self.assertTrue(q > p)
  194. self.assertTrue(q >= p)
  195. self.assertFalse(q < r)
  196. self.assertFalse(q <= r)
  197. self.assertFalse(q > r)
  198. self.assertFalse(q >= r)
  199. self.assertTrue(set('a').issubset('abc'))
  200. self.assertTrue(set('abc').issuperset('a'))
  201. self.assertFalse(set('a').issubset('cbs'))
  202. self.assertFalse(set('cbs').issuperset('a'))
  203. def test_pickling(self):
  204. for i in range(pickle.HIGHEST_PROTOCOL + 1):
  205. if type(self.s) not in (set, frozenset):
  206. self.s.x = ['x']
  207. self.s.z = ['z']
  208. p = pickle.dumps(self.s, i)
  209. dup = pickle.loads(p)
  210. self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
  211. if type(self.s) not in (set, frozenset):
  212. self.assertEqual(self.s.x, dup.x)
  213. self.assertEqual(self.s.z, dup.z)
  214. self.assertFalse(hasattr(self.s, 'y'))
  215. del self.s.x, self.s.z
  216. def test_iterator_pickling(self):
  217. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  218. itorg = iter(self.s)
  219. data = self.thetype(self.s)
  220. d = pickle.dumps(itorg, proto)
  221. it = pickle.loads(d)
  222. # Set iterators unpickle as list iterators due to the
  223. # undefined order of set items.
  224. # self.assertEqual(type(itorg), type(it))
  225. self.assertIsInstance(it, collections.abc.Iterator)
  226. self.assertEqual(self.thetype(it), data)
  227. it = pickle.loads(d)
  228. try:
  229. drop = next(it)
  230. except StopIteration:
  231. continue
  232. d = pickle.dumps(it, proto)
  233. it = pickle.loads(d)
  234. self.assertEqual(self.thetype(it), data - self.thetype((drop,)))
  235. def test_deepcopy(self):
  236. class Tracer:
  237. def __init__(self, value):
  238. self.value = value
  239. def __hash__(self):
  240. return self.value
  241. def __deepcopy__(self, memo=None):
  242. return Tracer(self.value + 1)
  243. t = Tracer(10)
  244. s = self.thetype([t])
  245. dup = copy.deepcopy(s)
  246. self.assertNotEqual(id(s), id(dup))
  247. for elem in dup:
  248. newt = elem
  249. self.assertNotEqual(id(t), id(newt))
  250. self.assertEqual(t.value + 1, newt.value)
  251. def test_gc(self):
  252. # Create a nest of cycles to exercise overall ref count check
  253. class A:
  254. pass
  255. s = set(A() for i in range(1000))
  256. for elem in s:
  257. elem.cycle = s
  258. elem.sub = elem
  259. elem.set = set([elem])
  260. def test_subclass_with_custom_hash(self):
  261. # Bug #1257731
  262. class H(self.thetype):
  263. def __hash__(self):
  264. return int(id(self) & 0x7fffffff)
  265. s=H()
  266. f=set()
  267. f.add(s)
  268. self.assertIn(s, f)
  269. f.remove(s)
  270. f.add(s)
  271. f.discard(s)
  272. def test_badcmp(self):
  273. s = self.thetype([BadCmp()])
  274. # Detect comparison errors during insertion and lookup
  275. self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()])
  276. self.assertRaises(RuntimeError, s.__contains__, BadCmp())
  277. # Detect errors during mutating operations
  278. if hasattr(s, 'add'):
  279. self.assertRaises(RuntimeError, s.add, BadCmp())
  280. self.assertRaises(RuntimeError, s.discard, BadCmp())
  281. self.assertRaises(RuntimeError, s.remove, BadCmp())
  282. def test_cyclical_repr(self):
  283. w = ReprWrapper()
  284. s = self.thetype([w])
  285. w.value = s
  286. if self.thetype == set:
  287. self.assertEqual(repr(s), '{set(...)}')
  288. else:
  289. name = repr(s).partition('(')[0] # strip class name
  290. self.assertEqual(repr(s), '%s({%s(...)})' % (name, name))
  291. def test_do_not_rehash_dict_keys(self):
  292. n = 10
  293. d = dict.fromkeys(map(HashCountingInt, range(n)))
  294. self.assertEqual(sum(elem.hash_count for elem in d), n)
  295. s = self.thetype(d)
  296. self.assertEqual(sum(elem.hash_count for elem in d), n)
  297. s.difference(d)
  298. self.assertEqual(sum(elem.hash_count for elem in d), n)
  299. if hasattr(s, 'symmetric_difference_update'):
  300. s.symmetric_difference_update(d)
  301. self.assertEqual(sum(elem.hash_count for elem in d), n)
  302. d2 = dict.fromkeys(set(d))
  303. self.assertEqual(sum(elem.hash_count for elem in d), n)
  304. d3 = dict.fromkeys(frozenset(d))
  305. self.assertEqual(sum(elem.hash_count for elem in d), n)
  306. d3 = dict.fromkeys(frozenset(d), 123)
  307. self.assertEqual(sum(elem.hash_count for elem in d), n)
  308. self.assertEqual(d3, dict.fromkeys(d, 123))
  309. def test_container_iterator(self):
  310. # Bug #3680: tp_traverse was not implemented for set iterator object
  311. class C(object):
  312. pass
  313. obj = C()
  314. ref = weakref.ref(obj)
  315. container = set([obj, 1])
  316. obj.x = iter(container)
  317. del obj, container
  318. gc.collect()
  319. self.assertTrue(ref() is None, "Cycle was not collected")
  320. def test_free_after_iterating(self):
  321. support.check_free_after_iterating(self, iter, self.thetype)
  322. class TestSet(TestJointOps, unittest.TestCase):
  323. thetype = set
  324. basetype = set
  325. def test_init(self):
  326. s = self.thetype()
  327. s.__init__(self.word)
  328. self.assertEqual(s, set(self.word))
  329. s.__init__(self.otherword)
  330. self.assertEqual(s, set(self.otherword))
  331. self.assertRaises(TypeError, s.__init__, s, 2)
  332. self.assertRaises(TypeError, s.__init__, 1)
  333. def test_constructor_identity(self):
  334. s = self.thetype(range(3))
  335. t = self.thetype(s)
  336. self.assertNotEqual(id(s), id(t))
  337. def test_set_literal(self):
  338. s = set([1,2,3])
  339. t = {1,2,3}
  340. self.assertEqual(s, t)
  341. def test_set_literal_insertion_order(self):
  342. # SF Issue #26020 -- Expect left to right insertion
  343. s = {1, 1.0, True}
  344. self.assertEqual(len(s), 1)
  345. stored_value = s.pop()
  346. self.assertEqual(type(stored_value), int)
  347. def test_set_literal_evaluation_order(self):
  348. # Expect left to right expression evaluation
  349. events = []
  350. def record(obj):
  351. events.append(obj)
  352. s = {record(1), record(2), record(3)}
  353. self.assertEqual(events, [1, 2, 3])
  354. def test_hash(self):
  355. self.assertRaises(TypeError, hash, self.s)
  356. def test_clear(self):
  357. self.s.clear()
  358. self.assertEqual(self.s, set())
  359. self.assertEqual(len(self.s), 0)
  360. def test_copy(self):
  361. dup = self.s.copy()
  362. self.assertEqual(self.s, dup)
  363. self.assertNotEqual(id(self.s), id(dup))
  364. self.assertEqual(type(dup), self.basetype)
  365. def test_add(self):
  366. self.s.add('Q')
  367. self.assertIn('Q', self.s)
  368. dup = self.s.copy()
  369. self.s.add('Q')
  370. self.assertEqual(self.s, dup)
  371. self.assertRaises(TypeError, self.s.add, [])
  372. def test_remove(self):
  373. self.s.remove('a')
  374. self.assertNotIn('a', self.s)
  375. self.assertRaises(KeyError, self.s.remove, 'Q')
  376. self.assertRaises(TypeError, self.s.remove, [])
  377. s = self.thetype([frozenset(self.word)])
  378. self.assertIn(self.thetype(self.word), s)
  379. s.remove(self.thetype(self.word))
  380. self.assertNotIn(self.thetype(self.word), s)
  381. self.assertRaises(KeyError, self.s.remove, self.thetype(self.word))
  382. def test_remove_keyerror_unpacking(self):
  383. # bug: www.python.org/sf/1576657
  384. for v1 in ['Q', (1,)]:
  385. try:
  386. self.s.remove(v1)
  387. except KeyError as e:
  388. v2 = e.args[0]
  389. self.assertEqual(v1, v2)
  390. else:
  391. self.fail()
  392. def test_remove_keyerror_set(self):
  393. key = self.thetype([3, 4])
  394. try:
  395. self.s.remove(key)
  396. except KeyError as e:
  397. self.assertTrue(e.args[0] is key,
  398. "KeyError should be {0}, not {1}".format(key,
  399. e.args[0]))
  400. else:
  401. self.fail()
  402. def test_discard(self):
  403. self.s.discard('a')
  404. self.assertNotIn('a', self.s)
  405. self.s.discard('Q')
  406. self.assertRaises(TypeError, self.s.discard, [])
  407. s = self.thetype([frozenset(self.word)])
  408. self.assertIn(self.thetype(self.word), s)
  409. s.discard(self.thetype(self.word))
  410. self.assertNotIn(self.thetype(self.word), s)
  411. s.discard(self.thetype(self.word))
  412. def test_pop(self):
  413. for i in range(len(self.s)):
  414. elem = self.s.pop()
  415. self.assertNotIn(elem, self.s)
  416. self.assertRaises(KeyError, self.s.pop)
  417. def test_update(self):
  418. retval = self.s.update(self.otherword)
  419. self.assertEqual(retval, None)
  420. for c in (self.word + self.otherword):
  421. self.assertIn(c, self.s)
  422. self.assertRaises(PassThru, self.s.update, check_pass_thru())
  423. self.assertRaises(TypeError, self.s.update, [[]])
  424. for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')):
  425. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  426. s = self.thetype('abcba')
  427. self.assertEqual(s.update(C(p)), None)
  428. self.assertEqual(s, set(q))
  429. for p in ('cdc', 'efgfe', 'ccb', 'ef', 'abcda'):
  430. q = 'ahi'
  431. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  432. s = self.thetype('abcba')
  433. self.assertEqual(s.update(C(p), C(q)), None)
  434. self.assertEqual(s, set(s) | set(p) | set(q))
  435. def test_ior(self):
  436. self.s |= set(self.otherword)
  437. for c in (self.word + self.otherword):
  438. self.assertIn(c, self.s)
  439. def test_intersection_update(self):
  440. retval = self.s.intersection_update(self.otherword)
  441. self.assertEqual(retval, None)
  442. for c in (self.word + self.otherword):
  443. if c in self.otherword and c in self.word:
  444. self.assertIn(c, self.s)
  445. else:
  446. self.assertNotIn(c, self.s)
  447. self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru())
  448. self.assertRaises(TypeError, self.s.intersection_update, [[]])
  449. for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')):
  450. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  451. s = self.thetype('abcba')
  452. self.assertEqual(s.intersection_update(C(p)), None)
  453. self.assertEqual(s, set(q))
  454. ss = 'abcba'
  455. s = self.thetype(ss)
  456. t = 'cbc'
  457. self.assertEqual(s.intersection_update(C(p), C(t)), None)
  458. self.assertEqual(s, set('abcba')&set(p)&set(t))
  459. def test_iand(self):
  460. self.s &= set(self.otherword)
  461. for c in (self.word + self.otherword):
  462. if c in self.otherword and c in self.word:
  463. self.assertIn(c, self.s)
  464. else:
  465. self.assertNotIn(c, self.s)
  466. def test_difference_update(self):
  467. retval = self.s.difference_update(self.otherword)
  468. self.assertEqual(retval, None)
  469. for c in (self.word + self.otherword):
  470. if c in self.word and c not in self.otherword:
  471. self.assertIn(c, self.s)
  472. else:
  473. self.assertNotIn(c, self.s)
  474. self.assertRaises(PassThru, self.s.difference_update, check_pass_thru())
  475. self.assertRaises(TypeError, self.s.difference_update, [[]])
  476. self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
  477. for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')):
  478. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  479. s = self.thetype('abcba')
  480. self.assertEqual(s.difference_update(C(p)), None)
  481. self.assertEqual(s, set(q))
  482. s = self.thetype('abcdefghih')
  483. s.difference_update()
  484. self.assertEqual(s, self.thetype('abcdefghih'))
  485. s = self.thetype('abcdefghih')
  486. s.difference_update(C('aba'))
  487. self.assertEqual(s, self.thetype('cdefghih'))
  488. s = self.thetype('abcdefghih')
  489. s.difference_update(C('cdc'), C('aba'))
  490. self.assertEqual(s, self.thetype('efghih'))
  491. def test_isub(self):
  492. self.s -= set(self.otherword)
  493. for c in (self.word + self.otherword):
  494. if c in self.word and c not in self.otherword:
  495. self.assertIn(c, self.s)
  496. else:
  497. self.assertNotIn(c, self.s)
  498. def test_symmetric_difference_update(self):
  499. retval = self.s.symmetric_difference_update(self.otherword)
  500. self.assertEqual(retval, None)
  501. for c in (self.word + self.otherword):
  502. if (c in self.word) ^ (c in self.otherword):
  503. self.assertIn(c, self.s)
  504. else:
  505. self.assertNotIn(c, self.s)
  506. self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru())
  507. self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]])
  508. for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')):
  509. for C in set, frozenset, dict.fromkeys, str, list, tuple:
  510. s = self.thetype('abcba')
  511. self.assertEqual(s.symmetric_difference_update(C(p)), None)
  512. self.assertEqual(s, set(q))
  513. def test_ixor(self):
  514. self.s ^= set(self.otherword)
  515. for c in (self.word + self.otherword):
  516. if (c in self.word) ^ (c in self.otherword):
  517. self.assertIn(c, self.s)
  518. else:
  519. self.assertNotIn(c, self.s)
  520. def test_inplace_on_self(self):
  521. t = self.s.copy()
  522. t |= t
  523. self.assertEqual(t, self.s)
  524. t &= t
  525. self.assertEqual(t, self.s)
  526. t -= t
  527. self.assertEqual(t, self.thetype())
  528. t = self.s.copy()
  529. t ^= t
  530. self.assertEqual(t, self.thetype())
  531. def test_weakref(self):
  532. s = self.thetype('gallahad')
  533. p = weakref.proxy(s)
  534. self.assertEqual(str(p), str(s))
  535. s = None
  536. support.gc_collect() # For PyPy or other GCs.
  537. self.assertRaises(ReferenceError, str, p)
  538. def test_rich_compare(self):
  539. class TestRichSetCompare:
  540. def __gt__(self, some_set):
  541. self.gt_called = True
  542. return False
  543. def __lt__(self, some_set):
  544. self.lt_called = True
  545. return False
  546. def __ge__(self, some_set):
  547. self.ge_called = True
  548. return False
  549. def __le__(self, some_set):
  550. self.le_called = True
  551. return False
  552. # This first tries the builtin rich set comparison, which doesn't know
  553. # how to handle the custom object. Upon returning NotImplemented, the
  554. # corresponding comparison on the right object is invoked.
  555. myset = {1, 2, 3}
  556. myobj = TestRichSetCompare()
  557. myset < myobj
  558. self.assertTrue(myobj.gt_called)
  559. myobj = TestRichSetCompare()
  560. myset > myobj
  561. self.assertTrue(myobj.lt_called)
  562. myobj = TestRichSetCompare()
  563. myset <= myobj
  564. self.assertTrue(myobj.ge_called)
  565. myobj = TestRichSetCompare()
  566. myset >= myobj
  567. self.assertTrue(myobj.le_called)
  568. @unittest.skipUnless(hasattr(set, "test_c_api"),
  569. 'C API test only available in a debug build')
  570. def test_c_api(self):
  571. self.assertEqual(set().test_c_api(), True)
  572. class SetSubclass(set):
  573. pass
  574. class TestSetSubclass(TestSet):
  575. thetype = SetSubclass
  576. basetype = set
  577. def test_keywords_in_subclass(self):
  578. class subclass(set):
  579. pass
  580. u = subclass([1, 2])
  581. self.assertIs(type(u), subclass)
  582. self.assertEqual(set(u), {1, 2})
  583. with self.assertRaises(TypeError):
  584. subclass(sequence=())
  585. class subclass_with_init(set):
  586. def __init__(self, arg, newarg=None):
  587. super().__init__(arg)
  588. self.newarg = newarg
  589. u = subclass_with_init([1, 2], newarg=3)
  590. self.assertIs(type(u), subclass_with_init)
  591. self.assertEqual(set(u), {1, 2})
  592. self.assertEqual(u.newarg, 3)
  593. class subclass_with_new(set):
  594. def __new__(cls, arg, newarg=None):
  595. self = super().__new__(cls, arg)
  596. self.newarg = newarg
  597. return self
  598. u = subclass_with_new([1, 2])
  599. self.assertIs(type(u), subclass_with_new)
  600. self.assertEqual(set(u), {1, 2})
  601. self.assertIsNone(u.newarg)
  602. # disallow kwargs in __new__ only (https://bugs.python.org/issue43413#msg402000)
  603. with self.assertRaises(TypeError):
  604. subclass_with_new([1, 2], newarg=3)
  605. class TestFrozenSet(TestJointOps, unittest.TestCase):
  606. thetype = frozenset
  607. basetype = frozenset
  608. def test_init(self):
  609. s = self.thetype(self.word)
  610. s.__init__(self.otherword)
  611. self.assertEqual(s, set(self.word))
  612. def test_constructor_identity(self):
  613. s = self.thetype(range(3))
  614. t = self.thetype(s)
  615. self.assertEqual(id(s), id(t))
  616. def test_hash(self):
  617. self.assertEqual(hash(self.thetype('abcdeb')),
  618. hash(self.thetype('ebecda')))
  619. # make sure that all permutations give the same hash value
  620. n = 100
  621. seq = [randrange(n) for i in range(n)]
  622. results = set()
  623. for i in range(200):
  624. shuffle(seq)
  625. results.add(hash(self.thetype(seq)))
  626. self.assertEqual(len(results), 1)
  627. def test_copy(self):
  628. dup = self.s.copy()
  629. self.assertEqual(id(self.s), id(dup))
  630. def test_frozen_as_dictkey(self):
  631. seq = list(range(10)) + list('abcdefg') + ['apple']
  632. key1 = self.thetype(seq)
  633. key2 = self.thetype(reversed(seq))
  634. self.assertEqual(key1, key2)
  635. self.assertNotEqual(id(key1), id(key2))
  636. d = {}
  637. d[key1] = 42
  638. self.assertEqual(d[key2], 42)
  639. def test_hash_caching(self):
  640. f = self.thetype('abcdcda')
  641. self.assertEqual(hash(f), hash(f))
  642. def test_hash_effectiveness(self):
  643. n = 13
  644. hashvalues = set()
  645. addhashvalue = hashvalues.add
  646. elemmasks = [(i+1, 1<<i) for i in range(n)]
  647. for i in range(2**n):
  648. addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
  649. self.assertEqual(len(hashvalues), 2**n)
  650. def zf_range(n):
  651. # https://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers
  652. nums = [frozenset()]
  653. for i in range(n-1):
  654. num = frozenset(nums)
  655. nums.append(num)
  656. return nums[:n]
  657. def powerset(s):
  658. for i in range(len(s)+1):
  659. yield from map(frozenset, itertools.combinations(s, i))
  660. for n in range(18):
  661. t = 2 ** n
  662. mask = t - 1
  663. for nums in (range, zf_range):
  664. u = len({h & mask for h in map(hash, powerset(nums(n)))})
  665. self.assertGreater(4*u, t)
  666. class FrozenSetSubclass(frozenset):
  667. pass
  668. class TestFrozenSetSubclass(TestFrozenSet):
  669. thetype = FrozenSetSubclass
  670. basetype = frozenset
  671. def test_keywords_in_subclass(self):
  672. class subclass(frozenset):
  673. pass
  674. u = subclass([1, 2])
  675. self.assertIs(type(u), subclass)
  676. self.assertEqual(set(u), {1, 2})
  677. with self.assertRaises(TypeError):
  678. subclass(sequence=())
  679. class subclass_with_init(frozenset):
  680. def __init__(self, arg, newarg=None):
  681. self.newarg = newarg
  682. u = subclass_with_init([1, 2], newarg=3)
  683. self.assertIs(type(u), subclass_with_init)
  684. self.assertEqual(set(u), {1, 2})
  685. self.assertEqual(u.newarg, 3)
  686. class subclass_with_new(frozenset):
  687. def __new__(cls, arg, newarg=None):
  688. self = super().__new__(cls, arg)
  689. self.newarg = newarg
  690. return self
  691. u = subclass_with_new([1, 2], newarg=3)
  692. self.assertIs(type(u), subclass_with_new)
  693. self.assertEqual(set(u), {1, 2})
  694. self.assertEqual(u.newarg, 3)
  695. def test_constructor_identity(self):
  696. s = self.thetype(range(3))
  697. t = self.thetype(s)
  698. self.assertNotEqual(id(s), id(t))
  699. def test_copy(self):
  700. dup = self.s.copy()
  701. self.assertNotEqual(id(self.s), id(dup))
  702. def test_nested_empty_constructor(self):
  703. s = self.thetype()
  704. t = self.thetype(s)
  705. self.assertEqual(s, t)
  706. def test_singleton_empty_frozenset(self):
  707. Frozenset = self.thetype
  708. f = frozenset()
  709. F = Frozenset()
  710. efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
  711. Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''),
  712. Frozenset(range(0)), Frozenset(Frozenset()),
  713. Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)]
  714. # All empty frozenset subclass instances should have different ids
  715. self.assertEqual(len(set(map(id, efs))), len(efs))
  716. class SetSubclassWithSlots(set):
  717. __slots__ = ('x', 'y', '__dict__')
  718. class TestSetSubclassWithSlots(unittest.TestCase):
  719. thetype = SetSubclassWithSlots
  720. setUp = TestJointOps.setUp
  721. test_pickling = TestJointOps.test_pickling
  722. class FrozenSetSubclassWithSlots(frozenset):
  723. __slots__ = ('x', 'y', '__dict__')
  724. class TestFrozenSetSubclassWithSlots(TestSetSubclassWithSlots):
  725. thetype = FrozenSetSubclassWithSlots
  726. # Tests taken from test_sets.py =============================================
  727. empty_set = set()
  728. #==============================================================================
  729. class TestBasicOps:
  730. def test_repr(self):
  731. if self.repr is not None:
  732. self.assertEqual(repr(self.set), self.repr)
  733. def check_repr_against_values(self):
  734. text = repr(self.set)
  735. self.assertTrue(text.startswith('{'))
  736. self.assertTrue(text.endswith('}'))
  737. result = text[1:-1].split(', ')
  738. result.sort()
  739. sorted_repr_values = [repr(value) for value in self.values]
  740. sorted_repr_values.sort()
  741. self.assertEqual(result, sorted_repr_values)
  742. def test_length(self):
  743. self.assertEqual(len(self.set), self.length)
  744. def test_self_equality(self):
  745. self.assertEqual(self.set, self.set)
  746. def test_equivalent_equality(self):
  747. self.assertEqual(self.set, self.dup)
  748. def test_copy(self):
  749. self.assertEqual(self.set.copy(), self.dup)
  750. def test_self_union(self):
  751. result = self.set | self.set
  752. self.assertEqual(result, self.dup)
  753. def test_empty_union(self):
  754. result = self.set | empty_set
  755. self.assertEqual(result, self.dup)
  756. def test_union_empty(self):
  757. result = empty_set | self.set
  758. self.assertEqual(result, self.dup)
  759. def test_self_intersection(self):
  760. result = self.set & self.set
  761. self.assertEqual(result, self.dup)
  762. def test_empty_intersection(self):
  763. result = self.set & empty_set
  764. self.assertEqual(result, empty_set)
  765. def test_intersection_empty(self):
  766. result = empty_set & self.set
  767. self.assertEqual(result, empty_set)
  768. def test_self_isdisjoint(self):
  769. result = self.set.isdisjoint(self.set)
  770. self.assertEqual(result, not self.set)
  771. def test_empty_isdisjoint(self):
  772. result = self.set.isdisjoint(empty_set)
  773. self.assertEqual(result, True)
  774. def test_isdisjoint_empty(self):
  775. result = empty_set.isdisjoint(self.set)
  776. self.assertEqual(result, True)
  777. def test_self_symmetric_difference(self):
  778. result = self.set ^ self.set
  779. self.assertEqual(result, empty_set)
  780. def test_empty_symmetric_difference(self):
  781. result = self.set ^ empty_set
  782. self.assertEqual(result, self.set)
  783. def test_self_difference(self):
  784. result = self.set - self.set
  785. self.assertEqual(result, empty_set)
  786. def test_empty_difference(self):
  787. result = self.set - empty_set
  788. self.assertEqual(result, self.dup)
  789. def test_empty_difference_rev(self):
  790. result = empty_set - self.set
  791. self.assertEqual(result, empty_set)
  792. def test_iteration(self):
  793. for v in self.set:
  794. self.assertIn(v, self.values)
  795. setiter = iter(self.set)
  796. self.assertEqual(setiter.__length_hint__(), len(self.set))
  797. def test_pickling(self):
  798. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  799. p = pickle.dumps(self.set, proto)
  800. copy = pickle.loads(p)
  801. self.assertEqual(self.set, copy,
  802. "%s != %s" % (self.set, copy))
  803. def test_issue_37219(self):
  804. with self.assertRaises(TypeError):
  805. set().difference(123)
  806. with self.assertRaises(TypeError):
  807. set().difference_update(123)
  808. #------------------------------------------------------------------------------
  809. class TestBasicOpsEmpty(TestBasicOps, unittest.TestCase):
  810. def setUp(self):
  811. self.case = "empty set"
  812. self.values = []
  813. self.set = set(self.values)
  814. self.dup = set(self.values)
  815. self.length = 0
  816. self.repr = "set()"
  817. #------------------------------------------------------------------------------
  818. class TestBasicOpsSingleton(TestBasicOps, unittest.TestCase):
  819. def setUp(self):
  820. self.case = "unit set (number)"
  821. self.values = [3]
  822. self.set = set(self.values)
  823. self.dup = set(self.values)
  824. self.length = 1
  825. self.repr = "{3}"
  826. def test_in(self):
  827. self.assertIn(3, self.set)
  828. def test_not_in(self):
  829. self.assertNotIn(2, self.set)
  830. #------------------------------------------------------------------------------
  831. class TestBasicOpsTuple(TestBasicOps, unittest.TestCase):
  832. def setUp(self):
  833. self.case = "unit set (tuple)"
  834. self.values = [(0, "zero")]
  835. self.set = set(self.values)
  836. self.dup = set(self.values)
  837. self.length = 1
  838. self.repr = "{(0, 'zero')}"
  839. def test_in(self):
  840. self.assertIn((0, "zero"), self.set)
  841. def test_not_in(self):
  842. self.assertNotIn(9, self.set)
  843. #------------------------------------------------------------------------------
  844. class TestBasicOpsTriple(TestBasicOps, unittest.TestCase):
  845. def setUp(self):
  846. self.case = "triple set"
  847. self.values = [0, "zero", operator.add]
  848. self.set = set(self.values)
  849. self.dup = set(self.values)
  850. self.length = 3
  851. self.repr = None
  852. #------------------------------------------------------------------------------
  853. class TestBasicOpsString(TestBasicOps, unittest.TestCase):
  854. def setUp(self):
  855. self.case = "string set"
  856. self.values = ["a", "b", "c"]
  857. self.set = set(self.values)
  858. self.dup = set(self.values)
  859. self.length = 3
  860. def test_repr(self):
  861. self.check_repr_against_values()
  862. #------------------------------------------------------------------------------
  863. class TestBasicOpsBytes(TestBasicOps, unittest.TestCase):
  864. def setUp(self):
  865. self.case = "bytes set"
  866. self.values = [b"a", b"b", b"c"]
  867. self.set = set(self.values)
  868. self.dup = set(self.values)
  869. self.length = 3
  870. def test_repr(self):
  871. self.check_repr_against_values()
  872. #------------------------------------------------------------------------------
  873. class TestBasicOpsMixedStringBytes(TestBasicOps, unittest.TestCase):
  874. def setUp(self):
  875. self.enterContext(warnings_helper.check_warnings())
  876. warnings.simplefilter('ignore', BytesWarning)
  877. self.case = "string and bytes set"
  878. self.values = ["a", "b", b"a", b"b"]
  879. self.set = set(self.values)
  880. self.dup = set(self.values)
  881. self.length = 4
  882. def test_repr(self):
  883. self.check_repr_against_values()
  884. #==============================================================================
  885. def baditer():
  886. raise TypeError
  887. yield True
  888. def gooditer():
  889. yield True
  890. class TestExceptionPropagation(unittest.TestCase):
  891. """SF 628246: Set constructor should not trap iterator TypeErrors"""
  892. def test_instanceWithException(self):
  893. self.assertRaises(TypeError, set, baditer())
  894. def test_instancesWithoutException(self):
  895. # All of these iterables should load without exception.
  896. set([1,2,3])
  897. set((1,2,3))
  898. set({'one':1, 'two':2, 'three':3})
  899. set(range(3))
  900. set('abc')
  901. set(gooditer())
  902. def test_changingSizeWhileIterating(self):
  903. s = set([1,2,3])
  904. try:
  905. for i in s:
  906. s.update([4])
  907. except RuntimeError:
  908. pass
  909. else:
  910. self.fail("no exception when changing size during iteration")
  911. #==============================================================================
  912. class TestSetOfSets(unittest.TestCase):
  913. def test_constructor(self):
  914. inner = frozenset([1])
  915. outer = set([inner])
  916. element = outer.pop()
  917. self.assertEqual(type(element), frozenset)
  918. outer.add(inner) # Rebuild set of sets with .add method
  919. outer.remove(inner)
  920. self.assertEqual(outer, set()) # Verify that remove worked
  921. outer.discard(inner) # Absence of KeyError indicates working fine
  922. #==============================================================================
  923. class TestBinaryOps(unittest.TestCase):
  924. def setUp(self):
  925. self.set = set((2, 4, 6))
  926. def test_eq(self): # SF bug 643115
  927. self.assertEqual(self.set, set({2:1,4:3,6:5}))
  928. def test_union_subset(self):
  929. result = self.set | set([2])
  930. self.assertEqual(result, set((2, 4, 6)))
  931. def test_union_superset(self):
  932. result = self.set | set([2, 4, 6, 8])
  933. self.assertEqual(result, set([2, 4, 6, 8]))
  934. def test_union_overlap(self):
  935. result = self.set | set([3, 4, 5])
  936. self.assertEqual(result, set([2, 3, 4, 5, 6]))
  937. def test_union_non_overlap(self):
  938. result = self.set | set([8])
  939. self.assertEqual(result, set([2, 4, 6, 8]))
  940. def test_intersection_subset(self):
  941. result = self.set & set((2, 4))
  942. self.assertEqual(result, set((2, 4)))
  943. def test_intersection_superset(self):
  944. result = self.set & set([2, 4, 6, 8])
  945. self.assertEqual(result, set([2, 4, 6]))
  946. def test_intersection_overlap(self):
  947. result = self.set & set([3, 4, 5])
  948. self.assertEqual(result, set([4]))
  949. def test_intersection_non_overlap(self):
  950. result = self.set & set([8])
  951. self.assertEqual(result, empty_set)
  952. def test_isdisjoint_subset(self):
  953. result = self.set.isdisjoint(set((2, 4)))
  954. self.assertEqual(result, False)
  955. def test_isdisjoint_superset(self):
  956. result = self.set.isdisjoint(set([2, 4, 6, 8]))
  957. self.assertEqual(result, False)
  958. def test_isdisjoint_overlap(self):
  959. result = self.set.isdisjoint(set([3, 4, 5]))
  960. self.assertEqual(result, False)
  961. def test_isdisjoint_non_overlap(self):
  962. result = self.set.isdisjoint(set([8]))
  963. self.assertEqual(result, True)
  964. def test_sym_difference_subset(self):
  965. result = self.set ^ set((2, 4))
  966. self.assertEqual(result, set([6]))
  967. def test_sym_difference_superset(self):
  968. result = self.set ^ set((2, 4, 6, 8))
  969. self.assertEqual(result, set([8]))
  970. def test_sym_difference_overlap(self):
  971. result = self.set ^ set((3, 4, 5))
  972. self.assertEqual(result, set([2, 3, 5, 6]))
  973. def test_sym_difference_non_overlap(self):
  974. result = self.set ^ set([8])
  975. self.assertEqual(result, set([2, 4, 6, 8]))
  976. #==============================================================================
  977. class TestUpdateOps(unittest.TestCase):
  978. def setUp(self):
  979. self.set = set((2, 4, 6))
  980. def test_union_subset(self):
  981. self.set |= set([2])
  982. self.assertEqual(self.set, set((2, 4, 6)))
  983. def test_union_superset(self):
  984. self.set |= set([2, 4, 6, 8])
  985. self.assertEqual(self.set, set([2, 4, 6, 8]))
  986. def test_union_overlap(self):
  987. self.set |= set([3, 4, 5])
  988. self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
  989. def test_union_non_overlap(self):
  990. self.set |= set([8])
  991. self.assertEqual(self.set, set([2, 4, 6, 8]))
  992. def test_union_method_call(self):
  993. self.set.update(set([3, 4, 5]))
  994. self.assertEqual(self.set, set([2, 3, 4, 5, 6]))
  995. def test_intersection_subset(self):
  996. self.set &= set((2, 4))
  997. self.assertEqual(self.set, set((2, 4)))
  998. def test_intersection_superset(self):
  999. self.set &= set([2, 4, 6, 8])
  1000. self.assertEqual(self.set, set([2, 4, 6]))
  1001. def test_intersection_overlap(self):
  1002. self.set &= set([3, 4, 5])
  1003. self.assertEqual(self.set, set([4]))
  1004. def test_intersection_non_overlap(self):
  1005. self.set &= set([8])
  1006. self.assertEqual(self.set, empty_set)
  1007. def test_intersection_method_call(self):
  1008. self.set.intersection_update(set([3, 4, 5]))
  1009. self.assertEqual(self.set, set([4]))
  1010. def test_sym_difference_subset(self):
  1011. self.set ^= set((2, 4))
  1012. self.assertEqual(self.set, set([6]))
  1013. def test_sym_difference_superset(self):
  1014. self.set ^= set((2, 4, 6, 8))
  1015. self.assertEqual(self.set, set([8]))
  1016. def test_sym_difference_overlap(self):
  1017. self.set ^= set((3, 4, 5))
  1018. self.assertEqual(self.set, set([2, 3, 5, 6]))
  1019. def test_sym_difference_non_overlap(self):
  1020. self.set ^= set([8])
  1021. self.assertEqual(self.set, set([2, 4, 6, 8]))
  1022. def test_sym_difference_method_call(self):
  1023. self.set.symmetric_difference_update(set([3, 4, 5]))
  1024. self.assertEqual(self.set, set([2, 3, 5, 6]))
  1025. def test_difference_subset(self):
  1026. self.set -= set((2, 4))
  1027. self.assertEqual(self.set, set([6]))
  1028. def test_difference_superset(self):
  1029. self.set -= set((2, 4, 6, 8))
  1030. self.assertEqual(self.set, set([]))
  1031. def test_difference_overlap(self):
  1032. self.set -= set((3, 4, 5))
  1033. self.assertEqual(self.set, set([2, 6]))
  1034. def test_difference_non_overlap(self):
  1035. self.set -= set([8])
  1036. self.assertEqual(self.set, set([2, 4, 6]))
  1037. def test_difference_method_call(self):
  1038. self.set.difference_update(set([3, 4, 5]))
  1039. self.assertEqual(self.set, set([2, 6]))
  1040. #==============================================================================
  1041. class TestMutate(unittest.TestCase):
  1042. def setUp(self):
  1043. self.values = ["a", "b", "c"]
  1044. self.set = set(self.values)
  1045. def test_add_present(self):
  1046. self.set.add("c")
  1047. self.assertEqual(self.set, set("abc"))
  1048. def test_add_absent(self):
  1049. self.set.add("d")
  1050. self.assertEqual(self.set, set("abcd"))
  1051. def test_add_until_full(self):
  1052. tmp = set()
  1053. expected_len = 0
  1054. for v in self.values:
  1055. tmp.add(v)
  1056. expected_len += 1
  1057. self.assertEqual(len(tmp), expected_len)
  1058. self.assertEqual(tmp, self.set)
  1059. def test_remove_present(self):
  1060. self.set.remove("b")
  1061. self.assertEqual(self.set, set("ac"))
  1062. def test_remove_absent(self):
  1063. try:
  1064. self.set.remove("d")
  1065. self.fail("Removing missing element should have raised LookupError")
  1066. except LookupError:
  1067. pass
  1068. def test_remove_until_empty(self):
  1069. expected_len = len(self.set)
  1070. for v in self.values:
  1071. self.set.remove(v)
  1072. expected_len -= 1
  1073. self.assertEqual(len(self.set), expected_len)
  1074. def test_discard_present(self):
  1075. self.set.discard("c")
  1076. self.assertEqual(self.set, set("ab"))
  1077. def test_discard_absent(self):
  1078. self.set.discard("d")
  1079. self.assertEqual(self.set, set("abc"))
  1080. def test_clear(self):
  1081. self.set.clear()
  1082. self.assertEqual(len(self.set), 0)
  1083. def test_pop(self):
  1084. popped = {}
  1085. while self.set:
  1086. popped[self.set.pop()] = None
  1087. self.assertEqual(len(popped), len(self.values))
  1088. for v in self.values:
  1089. self.assertIn(v, popped)
  1090. def test_update_empty_tuple(self):
  1091. self.set.update(())
  1092. self.assertEqual(self.set, set(self.values))
  1093. def test_update_unit_tuple_overlap(self):
  1094. self.set.update(("a",))
  1095. self.assertEqual(self.set, set(self.values))
  1096. def test_update_unit_tuple_non_overlap(self):
  1097. self.set.update(("a", "z"))
  1098. self.assertEqual(self.set, set(self.values + ["z"]))
  1099. #==============================================================================
  1100. class TestSubsets:
  1101. case2method = {"<=": "issubset",
  1102. ">=": "issuperset",
  1103. }
  1104. reverse = {"==": "==",
  1105. "!=": "!=",
  1106. "<": ">",
  1107. ">": "<",
  1108. "<=": ">=",
  1109. ">=": "<=",
  1110. }
  1111. def test_issubset(self):
  1112. x = self.left
  1113. y = self.right
  1114. for case in "!=", "==", "<", "<=", ">", ">=":
  1115. expected = case in self.cases
  1116. # Test the binary infix spelling.
  1117. result = eval("x" + case + "y", locals())
  1118. self.assertEqual(result, expected)
  1119. # Test the "friendly" method-name spelling, if one exists.
  1120. if case in TestSubsets.case2method:
  1121. method = getattr(x, TestSubsets.case2method[case])
  1122. result = method(y)
  1123. self.assertEqual(result, expected)
  1124. # Now do the same for the operands reversed.
  1125. rcase = TestSubsets.reverse[case]
  1126. result = eval("y" + rcase + "x", locals())
  1127. self.assertEqual(result, expected)
  1128. if rcase in TestSubsets.case2method:
  1129. method = getattr(y, TestSubsets.case2method[rcase])
  1130. result = method(x)
  1131. self.assertEqual(result, expected)
  1132. #------------------------------------------------------------------------------
  1133. class TestSubsetEqualEmpty(TestSubsets, unittest.TestCase):
  1134. left = set()
  1135. right = set()
  1136. name = "both empty"
  1137. cases = "==", "<=", ">="
  1138. #------------------------------------------------------------------------------
  1139. class TestSubsetEqualNonEmpty(TestSubsets, unittest.TestCase):
  1140. left = set([1, 2])
  1141. right = set([1, 2])
  1142. name = "equal pair"
  1143. cases = "==", "<=", ">="
  1144. #------------------------------------------------------------------------------
  1145. class TestSubsetEmptyNonEmpty(TestSubsets, unittest.TestCase):
  1146. left = set()
  1147. right = set([1, 2])
  1148. name = "one empty, one non-empty"
  1149. cases = "!=", "<", "<="
  1150. #------------------------------------------------------------------------------
  1151. class TestSubsetPartial(TestSubsets, unittest.TestCase):
  1152. left = set([1])
  1153. right = set([1, 2])
  1154. name = "one a non-empty proper subset of other"
  1155. cases = "!=", "<", "<="
  1156. #------------------------------------------------------------------------------
  1157. class TestSubsetNonOverlap(TestSubsets, unittest.TestCase):
  1158. left = set([1])
  1159. right = set([2])
  1160. name = "neither empty, neither contains"
  1161. cases = "!="
  1162. #==============================================================================
  1163. class TestOnlySetsInBinaryOps:
  1164. def test_eq_ne(self):
  1165. # Unlike the others, this is testing that == and != *are* allowed.
  1166. self.assertEqual(self.other == self.set, False)
  1167. self.assertEqual(self.set == self.other, False)
  1168. self.assertEqual(self.other != self.set, True)
  1169. self.assertEqual(self.set != self.other, True)
  1170. def test_ge_gt_le_lt(self):
  1171. self.assertRaises(TypeError, lambda: self.set < self.other)
  1172. self.assertRaises(TypeError, lambda: self.set <= self.other)
  1173. self.assertRaises(TypeError, lambda: self.set > self.other)
  1174. self.assertRaises(TypeError, lambda: self.set >= self.other)
  1175. self.assertRaises(TypeError, lambda: self.other < self.set)
  1176. self.assertRaises(TypeError, lambda: self.other <= self.set)
  1177. self.assertRaises(TypeError, lambda: self.other > self.set)
  1178. self.assertRaises(TypeError, lambda: self.other >= self.set)
  1179. def test_update_operator(self):
  1180. try:
  1181. self.set |= self.other
  1182. except TypeError:
  1183. pass
  1184. else:
  1185. self.fail("expected TypeError")
  1186. def test_update(self):
  1187. if self.otherIsIterable:
  1188. self.set.update(self.other)
  1189. else:
  1190. self.assertRaises(TypeError, self.set.update, self.other)
  1191. def test_union(self):
  1192. self.assertRaises(TypeError, lambda: self.set | self.other)
  1193. self.assertRaises(TypeError, lambda: self.other | self.set)
  1194. if self.otherIsIterable:
  1195. self.set.union(self.other)
  1196. else:
  1197. self.assertRaises(TypeError, self.set.union, self.other)
  1198. def test_intersection_update_operator(self):
  1199. try:
  1200. self.set &= self.other
  1201. except TypeError:
  1202. pass
  1203. else:
  1204. self.fail("expected TypeError")
  1205. def test_intersection_update(self):
  1206. if self.otherIsIterable:
  1207. self.set.intersection_update(self.other)
  1208. else:
  1209. self.assertRaises(TypeError,
  1210. self.set.intersection_update,
  1211. self.other)
  1212. def test_intersection(self):
  1213. self.assertRaises(TypeError, lambda: self.set & self.other)
  1214. self.assertRaises(TypeError, lambda: self.other & self.set)
  1215. if self.otherIsIterable:
  1216. self.set.intersection(self.other)
  1217. else:
  1218. self.assertRaises(TypeError, self.set.intersection, self.other)
  1219. def test_sym_difference_update_operator(self):
  1220. try:
  1221. self.set ^= self.other
  1222. except TypeError:
  1223. pass
  1224. else:
  1225. self.fail("expected TypeError")
  1226. def test_sym_difference_update(self):
  1227. if self.otherIsIterable:
  1228. self.set.symmetric_difference_update(self.other)
  1229. else:
  1230. self.assertRaises(TypeError,
  1231. self.set.symmetric_difference_update,
  1232. self.other)
  1233. def test_sym_difference(self):
  1234. self.assertRaises(TypeError, lambda: self.set ^ self.other)
  1235. self.assertRaises(TypeError, lambda: self.other ^ self.set)
  1236. if self.otherIsIterable:
  1237. self.set.symmetric_difference(self.other)
  1238. else:
  1239. self.assertRaises(TypeError, self.set.symmetric_difference, self.other)
  1240. def test_difference_update_operator(self):
  1241. try:
  1242. self.set -= self.other
  1243. except TypeError:
  1244. pass
  1245. else:
  1246. self.fail("expected TypeError")
  1247. def test_difference_update(self):
  1248. if self.otherIsIterable:
  1249. self.set.difference_update(self.other)
  1250. else:
  1251. self.assertRaises(TypeError,
  1252. self.set.difference_update,
  1253. self.other)
  1254. def test_difference(self):
  1255. self.assertRaises(TypeError, lambda: self.set - self.other)
  1256. self.assertRaises(TypeError, lambda: self.other - self.set)
  1257. if self.otherIsIterable:
  1258. self.set.difference(self.other)
  1259. else:
  1260. self.assertRaises(TypeError, self.set.difference, self.other)
  1261. #------------------------------------------------------------------------------
  1262. class TestOnlySetsNumeric(TestOnlySetsInBinaryOps, unittest.TestCase):
  1263. def setUp(self):
  1264. self.set = set((1, 2, 3))
  1265. self.other = 19
  1266. self.otherIsIterable = False
  1267. #------------------------------------------------------------------------------
  1268. class TestOnlySetsDict(TestOnlySetsInBinaryOps, unittest.TestCase):
  1269. def setUp(self):
  1270. self.set = set((1, 2, 3))
  1271. self.other = {1:2, 3:4}
  1272. self.otherIsIterable = True
  1273. #------------------------------------------------------------------------------
  1274. class TestOnlySetsOperator(TestOnlySetsInBinaryOps, unittest.TestCase):
  1275. def setUp(self):
  1276. self.set = set((1, 2, 3))
  1277. self.other = operator.add
  1278. self.otherIsIterable = False
  1279. #------------------------------------------------------------------------------
  1280. class TestOnlySetsTuple(TestOnlySetsInBinaryOps, unittest.TestCase):
  1281. def setUp(self):
  1282. self.set = set((1, 2, 3))
  1283. self.other = (2, 4, 6)
  1284. self.otherIsIterable = True
  1285. #------------------------------------------------------------------------------
  1286. class TestOnlySetsString(TestOnlySetsInBinaryOps, unittest.TestCase):
  1287. def setUp(self):
  1288. self.set = set((1, 2, 3))
  1289. self.other = 'abc'
  1290. self.otherIsIterable = True
  1291. #------------------------------------------------------------------------------
  1292. class TestOnlySetsGenerator(TestOnlySetsInBinaryOps, unittest.TestCase):
  1293. def setUp(self):
  1294. def gen():
  1295. for i in range(0, 10, 2):
  1296. yield i
  1297. self.set = set((1, 2, 3))
  1298. self.other = gen()
  1299. self.otherIsIterable = True
  1300. #==============================================================================
  1301. class TestCopying:
  1302. def test_copy(self):
  1303. dup = self.set.copy()
  1304. dup_list = sorted(dup, key=repr)
  1305. set_list = sorted(self.set, key=repr)
  1306. self.assertEqual(len(dup_list), len(set_list))
  1307. for i in range(len(dup_list)):
  1308. self.assertTrue(dup_list[i] is set_list[i])
  1309. def test_deep_copy(self):
  1310. dup = copy.deepcopy(self.set)
  1311. ##print type(dup), repr(dup)
  1312. dup_list = sorted(dup, key=repr)
  1313. set_list = sorted(self.set, key=repr)
  1314. self.assertEqual(len(dup_list), len(set_list))
  1315. for i in range(len(dup_list)):
  1316. self.assertEqual(dup_list[i], set_list[i])
  1317. #------------------------------------------------------------------------------
  1318. class TestCopyingEmpty(TestCopying, unittest.TestCase):
  1319. def setUp(self):
  1320. self.set = set()
  1321. #------------------------------------------------------------------------------
  1322. class TestCopyingSingleton(TestCopying, unittest.TestCase):
  1323. def setUp(self):
  1324. self.set = set(["hello"])
  1325. #------------------------------------------------------------------------------
  1326. class TestCopyingTriple(TestCopying, unittest.TestCase):
  1327. def setUp(self):
  1328. self.set = set(["zero", 0, None])
  1329. #------------------------------------------------------------------------------
  1330. class TestCopyingTuple(TestCopying, unittest.TestCase):
  1331. def setUp(self):
  1332. self.set = set([(1, 2)])
  1333. #------------------------------------------------------------------------------
  1334. class TestCopyingNested(TestCopying, unittest.TestCase):
  1335. def setUp(self):
  1336. self.set = set([((1, 2), (3, 4))])
  1337. #==============================================================================
  1338. class TestIdentities(unittest.TestCase):
  1339. def setUp(self):
  1340. self.a = set('abracadabra')
  1341. self.b = set('alacazam')
  1342. def test_binopsVsSubsets(self):
  1343. a, b = self.a, self.b
  1344. self.assertTrue(a - b < a)
  1345. self.assertTrue(b - a < b)
  1346. self.assertTrue(a & b < a)
  1347. self.assertTrue(a & b < b)
  1348. self.assertTrue(a | b > a)
  1349. self.assertTrue(a | b > b)
  1350. self.assertTrue(a ^ b < a | b)
  1351. def test_commutativity(self):
  1352. a, b = self.a, self.b
  1353. self.assertEqual(a&b, b&a)
  1354. self.assertEqual(a|b, b|a)
  1355. self.assertEqual(a^b, b^a)
  1356. if a != b:
  1357. self.assertNotEqual(a-b, b-a)
  1358. def test_summations(self):
  1359. # check that sums of parts equal the whole
  1360. a, b = self.a, self.b
  1361. self.assertEqual((a-b)|(a&b)|(b-a), a|b)
  1362. self.assertEqual((a&b)|(a^b), a|b)
  1363. self.assertEqual(a|(b-a), a|b)
  1364. self.assertEqual((a-b)|b, a|b)
  1365. self.assertEqual((a-b)|(a&b), a)
  1366. self.assertEqual((b-a)|(a&b), b)
  1367. self.assertEqual((a-b)|(b-a), a^b)
  1368. def test_exclusion(self):
  1369. # check that inverse operations show non-overlap
  1370. a, b, zero = self.a, self.b, set()
  1371. self.assertEqual((a-b)&b, zero)
  1372. self.assertEqual((b-a)&a, zero)
  1373. self.assertEqual((a&b)&(a^b), zero)
  1374. # Tests derived from test_itertools.py =======================================
  1375. def R(seqn):
  1376. 'Regular generator'
  1377. for i in seqn:
  1378. yield i
  1379. class G:
  1380. 'Sequence using __getitem__'
  1381. def __init__(self, seqn):
  1382. self.seqn = seqn
  1383. def __getitem__(self, i):
  1384. return self.seqn[i]
  1385. class I:
  1386. 'Sequence using iterator protocol'
  1387. def __init__(self, seqn):
  1388. self.seqn = seqn
  1389. self.i = 0
  1390. def __iter__(self):
  1391. return self
  1392. def __next__(self):
  1393. if self.i >= len(self.seqn): raise StopIteration
  1394. v = self.seqn[self.i]
  1395. self.i += 1
  1396. return v
  1397. class Ig:
  1398. 'Sequence using iterator protocol defined with a generator'
  1399. def __init__(self, seqn):
  1400. self.seqn = seqn
  1401. self.i = 0
  1402. def __iter__(self):
  1403. for val in self.seqn:
  1404. yield val
  1405. class X:
  1406. 'Missing __getitem__ and __iter__'
  1407. def __init__(self, seqn):
  1408. self.seqn = seqn
  1409. self.i = 0
  1410. def __next__(self):
  1411. if self.i >= len(self.seqn): raise StopIteration
  1412. v = self.seqn[self.i]
  1413. self.i += 1
  1414. return v
  1415. class N:
  1416. 'Iterator missing __next__()'
  1417. def __init__(self, seqn):
  1418. self.seqn = seqn
  1419. self.i = 0
  1420. def __iter__(self):
  1421. return self
  1422. class E:
  1423. 'Test propagation of exceptions'
  1424. def __init__(self, seqn):
  1425. self.seqn = seqn
  1426. self.i = 0
  1427. def __iter__(self):
  1428. return self
  1429. def __next__(self):
  1430. 3 // 0
  1431. class S:
  1432. 'Test immediate stop'
  1433. def __init__(self, seqn):
  1434. pass
  1435. def __iter__(self):
  1436. return self
  1437. def __next__(self):
  1438. raise StopIteration
  1439. from itertools import chain
  1440. def L(seqn):
  1441. 'Test multiple tiers of iterators'
  1442. return chain(map(lambda x:x, R(Ig(G(seqn)))))
  1443. class TestVariousIteratorArgs(unittest.TestCase):
  1444. def test_constructor(self):
  1445. for cons in (set, frozenset):
  1446. for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
  1447. for g in (G, I, Ig, S, L, R):
  1448. self.assertEqual(sorted(cons(g(s)), key=repr), sorted(g(s), key=repr))
  1449. self.assertRaises(TypeError, cons , X(s))
  1450. self.assertRaises(TypeError, cons , N(s))
  1451. self.assertRaises(ZeroDivisionError, cons , E(s))
  1452. def test_inline_methods(self):
  1453. s = set('november')
  1454. for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
  1455. for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
  1456. for g in (G, I, Ig, L, R):
  1457. expected = meth(data)
  1458. actual = meth(g(data))
  1459. if isinstance(expected, bool):
  1460. self.assertEqual(actual, expected)
  1461. else:
  1462. self.assertEqual(sorted(actual, key=repr), sorted(expected, key=repr))
  1463. self.assertRaises(TypeError, meth, X(s))
  1464. self.assertRaises(TypeError, meth, N(s))
  1465. self.assertRaises(ZeroDivisionError, meth, E(s))
  1466. def test_inplace_methods(self):
  1467. for data in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5), 'december'):
  1468. for methname in ('update', 'intersection_update',
  1469. 'difference_update', 'symmetric_difference_update'):
  1470. for g in (G, I, Ig, S, L, R):
  1471. s = set('january')
  1472. t = s.copy()
  1473. getattr(s, methname)(list(g(data)))
  1474. getattr(t, methname)(g(data))
  1475. self.assertEqual(sorted(s, key=repr), sorted(t, key=repr))
  1476. self.assertRaises(TypeError, getattr(set('january'), methname), X(data))
  1477. self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
  1478. self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
  1479. class bad_eq:
  1480. def __eq__(self, other):
  1481. if be_bad:
  1482. set2.clear()
  1483. raise ZeroDivisionError
  1484. return self is other
  1485. def __hash__(self):
  1486. return 0
  1487. class bad_dict_clear:
  1488. def __eq__(self, other):
  1489. if be_bad:
  1490. dict2.clear()
  1491. return self is other
  1492. def __hash__(self):
  1493. return 0
  1494. class TestWeirdBugs(unittest.TestCase):
  1495. def test_8420_set_merge(self):
  1496. # This used to segfault
  1497. global be_bad, set2, dict2
  1498. be_bad = False
  1499. set1 = {bad_eq()}
  1500. set2 = {bad_eq() for i in range(75)}
  1501. be_bad = True
  1502. self.assertRaises(ZeroDivisionError, set1.update, set2)
  1503. be_bad = False
  1504. set1 = {bad_dict_clear()}
  1505. dict2 = {bad_dict_clear(): None}
  1506. be_bad = True
  1507. set1.symmetric_difference_update(dict2)
  1508. def test_iter_and_mutate(self):
  1509. # Issue #24581
  1510. s = set(range(100))
  1511. s.clear()
  1512. s.update(range(100))
  1513. si = iter(s)
  1514. s.clear()
  1515. a = list(range(100))
  1516. s.update(range(100))
  1517. list(si)
  1518. def test_merge_and_mutate(self):
  1519. class X:
  1520. def __hash__(self):
  1521. return hash(0)
  1522. def __eq__(self, o):
  1523. other.clear()
  1524. return False
  1525. other = set()
  1526. other = {X() for i in range(10)}
  1527. s = {0}
  1528. s.update(other)
  1529. class TestOperationsMutating:
  1530. """Regression test for bpo-46615"""
  1531. constructor1 = None
  1532. constructor2 = None
  1533. def make_sets_of_bad_objects(self):
  1534. class Bad:
  1535. def __eq__(self, other):
  1536. if not enabled:
  1537. return False
  1538. if randrange(20) == 0:
  1539. set1.clear()
  1540. if randrange(20) == 0:
  1541. set2.clear()
  1542. return bool(randrange(2))
  1543. def __hash__(self):
  1544. return randrange(2)
  1545. # Don't behave poorly during construction.
  1546. enabled = False
  1547. set1 = self.constructor1(Bad() for _ in range(randrange(50)))
  1548. set2 = self.constructor2(Bad() for _ in range(randrange(50)))
  1549. # Now start behaving poorly
  1550. enabled = True
  1551. return set1, set2
  1552. def check_set_op_does_not_crash(self, function):
  1553. for _ in range(100):
  1554. set1, set2 = self.make_sets_of_bad_objects()
  1555. try:
  1556. function(set1, set2)
  1557. except RuntimeError as e:
  1558. # Just make sure we don't crash here.
  1559. self.assertIn("changed size during iteration", str(e))
  1560. class TestBinaryOpsMutating(TestOperationsMutating):
  1561. def test_eq_with_mutation(self):
  1562. self.check_set_op_does_not_crash(lambda a, b: a == b)
  1563. def test_ne_with_mutation(self):
  1564. self.check_set_op_does_not_crash(lambda a, b: a != b)
  1565. def test_lt_with_mutation(self):
  1566. self.check_set_op_does_not_crash(lambda a, b: a < b)
  1567. def test_le_with_mutation(self):
  1568. self.check_set_op_does_not_crash(lambda a, b: a <= b)
  1569. def test_gt_with_mutation(self):
  1570. self.check_set_op_does_not_crash(lambda a, b: a > b)
  1571. def test_ge_with_mutation(self):
  1572. self.check_set_op_does_not_crash(lambda a, b: a >= b)
  1573. def test_and_with_mutation(self):
  1574. self.check_set_op_does_not_crash(lambda a, b: a & b)
  1575. def test_or_with_mutation(self):
  1576. self.check_set_op_does_not_crash(lambda a, b: a | b)
  1577. def test_sub_with_mutation(self):
  1578. self.check_set_op_does_not_crash(lambda a, b: a - b)
  1579. def test_xor_with_mutation(self):
  1580. self.check_set_op_does_not_crash(lambda a, b: a ^ b)
  1581. def test_iadd_with_mutation(self):
  1582. def f(a, b):
  1583. a &= b
  1584. self.check_set_op_does_not_crash(f)
  1585. def test_ior_with_mutation(self):
  1586. def f(a, b):
  1587. a |= b
  1588. self.check_set_op_does_not_crash(f)
  1589. def test_isub_with_mutation(self):
  1590. def f(a, b):
  1591. a -= b
  1592. self.check_set_op_does_not_crash(f)
  1593. def test_ixor_with_mutation(self):
  1594. def f(a, b):
  1595. a ^= b
  1596. self.check_set_op_does_not_crash(f)
  1597. def test_iteration_with_mutation(self):
  1598. def f1(a, b):
  1599. for x in a:
  1600. pass
  1601. for y in b:
  1602. pass
  1603. def f2(a, b):
  1604. for y in b:
  1605. pass
  1606. for x in a:
  1607. pass
  1608. def f3(a, b):
  1609. for x, y in zip(a, b):
  1610. pass
  1611. self.check_set_op_does_not_crash(f1)
  1612. self.check_set_op_does_not_crash(f2)
  1613. self.check_set_op_does_not_crash(f3)
  1614. class TestBinaryOpsMutating_Set_Set(TestBinaryOpsMutating, unittest.TestCase):
  1615. constructor1 = set
  1616. constructor2 = set
  1617. class TestBinaryOpsMutating_Subclass_Subclass(TestBinaryOpsMutating, unittest.TestCase):
  1618. constructor1 = SetSubclass
  1619. constructor2 = SetSubclass
  1620. class TestBinaryOpsMutating_Set_Subclass(TestBinaryOpsMutating, unittest.TestCase):
  1621. constructor1 = set
  1622. constructor2 = SetSubclass
  1623. class TestBinaryOpsMutating_Subclass_Set(TestBinaryOpsMutating, unittest.TestCase):
  1624. constructor1 = SetSubclass
  1625. constructor2 = set
  1626. class TestMethodsMutating(TestOperationsMutating):
  1627. def test_issubset_with_mutation(self):
  1628. self.check_set_op_does_not_crash(set.issubset)
  1629. def test_issuperset_with_mutation(self):
  1630. self.check_set_op_does_not_crash(set.issuperset)
  1631. def test_intersection_with_mutation(self):
  1632. self.check_set_op_does_not_crash(set.intersection)
  1633. def test_union_with_mutation(self):
  1634. self.check_set_op_does_not_crash(set.union)
  1635. def test_difference_with_mutation(self):
  1636. self.check_set_op_does_not_crash(set.difference)
  1637. def test_symmetric_difference_with_mutation(self):
  1638. self.check_set_op_does_not_crash(set.symmetric_difference)
  1639. def test_isdisjoint_with_mutation(self):
  1640. self.check_set_op_does_not_crash(set.isdisjoint)
  1641. def test_difference_update_with_mutation(self):
  1642. self.check_set_op_does_not_crash(set.difference_update)
  1643. def test_intersection_update_with_mutation(self):
  1644. self.check_set_op_does_not_crash(set.intersection_update)
  1645. def test_symmetric_difference_update_with_mutation(self):
  1646. self.check_set_op_does_not_crash(set.symmetric_difference_update)
  1647. def test_update_with_mutation(self):
  1648. self.check_set_op_does_not_crash(set.update)
  1649. class TestMethodsMutating_Set_Set(TestMethodsMutating, unittest.TestCase):
  1650. constructor1 = set
  1651. constructor2 = set
  1652. class TestMethodsMutating_Subclass_Subclass(TestMethodsMutating, unittest.TestCase):
  1653. constructor1 = SetSubclass
  1654. constructor2 = SetSubclass
  1655. class TestMethodsMutating_Set_Subclass(TestMethodsMutating, unittest.TestCase):
  1656. constructor1 = set
  1657. constructor2 = SetSubclass
  1658. class TestMethodsMutating_Subclass_Set(TestMethodsMutating, unittest.TestCase):
  1659. constructor1 = SetSubclass
  1660. constructor2 = set
  1661. class TestMethodsMutating_Set_Dict(TestMethodsMutating, unittest.TestCase):
  1662. constructor1 = set
  1663. constructor2 = dict.fromkeys
  1664. class TestMethodsMutating_Set_List(TestMethodsMutating, unittest.TestCase):
  1665. constructor1 = set
  1666. constructor2 = list
  1667. # Application tests (based on David Eppstein's graph recipes ====================================
  1668. def powerset(U):
  1669. """Generates all subsets of a set or sequence U."""
  1670. U = iter(U)
  1671. try:
  1672. x = frozenset([next(U)])
  1673. for S in powerset(U):
  1674. yield S
  1675. yield S | x
  1676. except StopIteration:
  1677. yield frozenset()
  1678. def cube(n):
  1679. """Graph of n-dimensional hypercube."""
  1680. singletons = [frozenset([x]) for x in range(n)]
  1681. return dict([(x, frozenset([x^s for s in singletons]))
  1682. for x in powerset(range(n))])
  1683. def linegraph(G):
  1684. """Graph, the vertices of which are edges of G,
  1685. with two vertices being adjacent iff the corresponding
  1686. edges share a vertex."""
  1687. L = {}
  1688. for x in G:
  1689. for y in G[x]:
  1690. nx = [frozenset([x,z]) for z in G[x] if z != y]
  1691. ny = [frozenset([y,z]) for z in G[y] if z != x]
  1692. L[frozenset([x,y])] = frozenset(nx+ny)
  1693. return L
  1694. def faces(G):
  1695. 'Return a set of faces in G. Where a face is a set of vertices on that face'
  1696. # currently limited to triangles,squares, and pentagons
  1697. f = set()
  1698. for v1, edges in G.items():
  1699. for v2 in edges:
  1700. for v3 in G[v2]:
  1701. if v1 == v3:
  1702. continue
  1703. if v1 in G[v3]:
  1704. f.add(frozenset([v1, v2, v3]))
  1705. else:
  1706. for v4 in G[v3]:
  1707. if v4 == v2:
  1708. continue
  1709. if v1 in G[v4]:
  1710. f.add(frozenset([v1, v2, v3, v4]))
  1711. else:
  1712. for v5 in G[v4]:
  1713. if v5 == v3 or v5 == v2:
  1714. continue
  1715. if v1 in G[v5]:
  1716. f.add(frozenset([v1, v2, v3, v4, v5]))
  1717. return f
  1718. class TestGraphs(unittest.TestCase):
  1719. def test_cube(self):
  1720. g = cube(3) # vert --> {v1, v2, v3}
  1721. vertices1 = set(g)
  1722. self.assertEqual(len(vertices1), 8) # eight vertices
  1723. for edge in g.values():
  1724. self.assertEqual(len(edge), 3) # each vertex connects to three edges
  1725. vertices2 = set(v for edges in g.values() for v in edges)
  1726. self.assertEqual(vertices1, vertices2) # edge vertices in original set
  1727. cubefaces = faces(g)
  1728. self.assertEqual(len(cubefaces), 6) # six faces
  1729. for face in cubefaces:
  1730. self.assertEqual(len(face), 4) # each face is a square
  1731. def test_cuboctahedron(self):
  1732. # http://en.wikipedia.org/wiki/Cuboctahedron
  1733. # 8 triangular faces and 6 square faces
  1734. # 12 identical vertices each connecting a triangle and square
  1735. g = cube(3)
  1736. cuboctahedron = linegraph(g) # V( --> {V1, V2, V3, V4}
  1737. self.assertEqual(len(cuboctahedron), 12)# twelve vertices
  1738. vertices = set(cuboctahedron)
  1739. for edges in cuboctahedron.values():
  1740. self.assertEqual(len(edges), 4) # each vertex connects to four other vertices
  1741. othervertices = set(edge for edges in cuboctahedron.values() for edge in edges)
  1742. self.assertEqual(vertices, othervertices) # edge vertices in original set
  1743. cubofaces = faces(cuboctahedron)
  1744. facesizes = collections.defaultdict(int)
  1745. for face in cubofaces:
  1746. facesizes[len(face)] += 1
  1747. self.assertEqual(facesizes[3], 8) # eight triangular faces
  1748. self.assertEqual(facesizes[4], 6) # six square faces
  1749. for vertex in cuboctahedron:
  1750. edge = vertex # Cuboctahedron vertices are edges in Cube
  1751. self.assertEqual(len(edge), 2) # Two cube vertices define an edge
  1752. for cubevert in edge:
  1753. self.assertIn(cubevert, g)
  1754. #==============================================================================
  1755. if __name__ == "__main__":
  1756. unittest.main()