mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	 dbc1752d41
			
		
	
	
		dbc1752d41
		
			
		
	
	
	
	
		
			
			Co-authored-by: kalyanr <kalyan.ben10@live.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Victor Stinner <vstinner@python.org>
		
			
				
	
	
		
			271 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import unittest
 | |
| 
 | |
| from test.support import import_helper
 | |
| 
 | |
| # Skip this test if the _testcapi, _testlimitedcapi or _testinternalcapi
 | |
| # modules aren't available.
 | |
| _testcapi = import_helper.import_module('_testcapi')
 | |
| _testlimitedcapi = import_helper.import_module('_testlimitedcapi')
 | |
| _testinternalcapi = import_helper.import_module('_testinternalcapi')
 | |
| 
 | |
| class set_subclass(set):
 | |
|     pass
 | |
| 
 | |
| class frozenset_subclass(frozenset):
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class BaseSetTests:
 | |
|     def assertImmutable(self, action, *args):
 | |
|         self.assertRaises(SystemError, action, frozenset(), *args)
 | |
|         self.assertRaises(SystemError, action, frozenset({1}), *args)
 | |
|         self.assertRaises(SystemError, action, frozenset_subclass(), *args)
 | |
|         self.assertRaises(SystemError, action, frozenset_subclass({1}), *args)
 | |
| 
 | |
| 
 | |
| class TestSetCAPI(BaseSetTests, unittest.TestCase):
 | |
|     def test_set_check(self):
 | |
|         check = _testlimitedcapi.set_check
 | |
|         self.assertTrue(check(set()))
 | |
|         self.assertTrue(check({1, 2}))
 | |
|         self.assertFalse(check(frozenset()))
 | |
|         self.assertTrue(check(set_subclass()))
 | |
|         self.assertFalse(check(frozenset_subclass()))
 | |
|         self.assertFalse(check(object()))
 | |
|         # CRASHES: check(NULL)
 | |
| 
 | |
|     def test_set_check_exact(self):
 | |
|         check = _testlimitedcapi.set_checkexact
 | |
|         self.assertTrue(check(set()))
 | |
|         self.assertTrue(check({1, 2}))
 | |
|         self.assertFalse(check(frozenset()))
 | |
|         self.assertFalse(check(set_subclass()))
 | |
|         self.assertFalse(check(frozenset_subclass()))
 | |
|         self.assertFalse(check(object()))
 | |
|         # CRASHES: check(NULL)
 | |
| 
 | |
|     def test_frozenset_check(self):
 | |
|         check = _testlimitedcapi.frozenset_check
 | |
|         self.assertFalse(check(set()))
 | |
|         self.assertTrue(check(frozenset()))
 | |
|         self.assertTrue(check(frozenset({1, 2})))
 | |
|         self.assertFalse(check(set_subclass()))
 | |
|         self.assertTrue(check(frozenset_subclass()))
 | |
|         self.assertFalse(check(object()))
 | |
|         # CRASHES: check(NULL)
 | |
| 
 | |
|     def test_frozenset_check_exact(self):
 | |
|         check = _testlimitedcapi.frozenset_checkexact
 | |
|         self.assertFalse(check(set()))
 | |
|         self.assertTrue(check(frozenset()))
 | |
|         self.assertTrue(check(frozenset({1, 2})))
 | |
|         self.assertFalse(check(set_subclass()))
 | |
|         self.assertFalse(check(frozenset_subclass()))
 | |
|         self.assertFalse(check(object()))
 | |
|         # CRASHES: check(NULL)
 | |
| 
 | |
|     def test_anyset_check(self):
 | |
|         check = _testlimitedcapi.anyset_check
 | |
|         self.assertTrue(check(set()))
 | |
|         self.assertTrue(check({1, 2}))
 | |
|         self.assertTrue(check(frozenset()))
 | |
|         self.assertTrue(check(frozenset({1, 2})))
 | |
|         self.assertTrue(check(set_subclass()))
 | |
|         self.assertTrue(check(frozenset_subclass()))
 | |
|         self.assertFalse(check(object()))
 | |
|         # CRASHES: check(NULL)
 | |
| 
 | |
|     def test_anyset_check_exact(self):
 | |
|         check = _testlimitedcapi.anyset_checkexact
 | |
|         self.assertTrue(check(set()))
 | |
|         self.assertTrue(check({1, 2}))
 | |
|         self.assertTrue(check(frozenset()))
 | |
|         self.assertTrue(check(frozenset({1, 2})))
 | |
|         self.assertFalse(check(set_subclass()))
 | |
|         self.assertFalse(check(frozenset_subclass()))
 | |
|         self.assertFalse(check(object()))
 | |
|         # CRASHES: check(NULL)
 | |
| 
 | |
|     def test_set_new(self):
 | |
|         set_new = _testlimitedcapi.set_new
 | |
|         self.assertEqual(set_new().__class__, set)
 | |
|         self.assertEqual(set_new(), set())
 | |
|         self.assertEqual(set_new((1, 1, 2)), {1, 2})
 | |
|         self.assertEqual(set_new([1, 1, 2]), {1, 2})
 | |
|         with self.assertRaisesRegex(TypeError, 'object is not iterable'):
 | |
|             set_new(object())
 | |
|         with self.assertRaisesRegex(TypeError, 'object is not iterable'):
 | |
|             set_new(1)
 | |
|         with self.assertRaisesRegex(TypeError, "unhashable type: 'dict'"):
 | |
|             set_new((1, {}))
 | |
| 
 | |
|     def test_frozenset_new(self):
 | |
|         frozenset_new = _testlimitedcapi.frozenset_new
 | |
|         self.assertEqual(frozenset_new().__class__, frozenset)
 | |
|         self.assertEqual(frozenset_new(), frozenset())
 | |
|         self.assertEqual(frozenset_new((1, 1, 2)), frozenset({1, 2}))
 | |
|         self.assertEqual(frozenset_new([1, 1, 2]), frozenset({1, 2}))
 | |
|         with self.assertRaisesRegex(TypeError, 'object is not iterable'):
 | |
|             frozenset_new(object())
 | |
|         with self.assertRaisesRegex(TypeError, 'object is not iterable'):
 | |
|             frozenset_new(1)
 | |
|         with self.assertRaisesRegex(TypeError, "unhashable type: 'dict'"):
 | |
|             frozenset_new((1, {}))
 | |
| 
 | |
|     def test_set_size(self):
 | |
|         get_size = _testlimitedcapi.set_size
 | |
|         self.assertEqual(get_size(set()), 0)
 | |
|         self.assertEqual(get_size(frozenset()), 0)
 | |
|         self.assertEqual(get_size({1, 1, 2}), 2)
 | |
|         self.assertEqual(get_size(frozenset({1, 1, 2})), 2)
 | |
|         self.assertEqual(get_size(set_subclass((1, 2, 3))), 3)
 | |
|         self.assertEqual(get_size(frozenset_subclass((1, 2, 3))), 3)
 | |
|         with self.assertRaises(SystemError):
 | |
|             get_size(object())
 | |
|         # CRASHES: get_size(NULL)
 | |
| 
 | |
|     def test_set_get_size(self):
 | |
|         get_size = _testcapi.set_get_size
 | |
|         self.assertEqual(get_size(set()), 0)
 | |
|         self.assertEqual(get_size(frozenset()), 0)
 | |
|         self.assertEqual(get_size({1, 1, 2}), 2)
 | |
|         self.assertEqual(get_size(frozenset({1, 1, 2})), 2)
 | |
|         self.assertEqual(get_size(set_subclass((1, 2, 3))), 3)
 | |
|         self.assertEqual(get_size(frozenset_subclass((1, 2, 3))), 3)
 | |
|         # CRASHES: get_size(NULL)
 | |
|         # CRASHES: get_size(object())
 | |
| 
 | |
|     def test_set_contains(self):
 | |
|         contains = _testlimitedcapi.set_contains
 | |
|         for cls in (set, frozenset, set_subclass, frozenset_subclass):
 | |
|             with self.subTest(cls=cls):
 | |
|                 instance = cls((1, 2))
 | |
|                 self.assertTrue(contains(instance, 1))
 | |
|                 self.assertFalse(contains(instance, 'missing'))
 | |
|                 with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"):
 | |
|                     contains(instance, [])
 | |
|         # CRASHES: contains(instance, NULL)
 | |
|         # CRASHES: contains(NULL, object())
 | |
|         # CRASHES: contains(NULL, NULL)
 | |
| 
 | |
|     def test_add(self):
 | |
|         add = _testlimitedcapi.set_add
 | |
|         for cls in (set, set_subclass):
 | |
|             with self.subTest(cls=cls):
 | |
|                 instance = cls((1, 2))
 | |
|                 self.assertEqual(add(instance, 1), 0)
 | |
|                 self.assertEqual(instance, {1, 2})
 | |
|                 self.assertEqual(add(instance, 3), 0)
 | |
|                 self.assertEqual(instance, {1, 2, 3})
 | |
|                 with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"):
 | |
|                     add(instance, [])
 | |
|         with self.assertRaises(SystemError):
 | |
|             add(object(), 1)
 | |
|         self.assertImmutable(add, 1)
 | |
|         # CRASHES: add(NULL, object())
 | |
|         # CRASHES: add(instance, NULL)
 | |
|         # CRASHES: add(NULL, NULL)
 | |
| 
 | |
|     def test_discard(self):
 | |
|         discard = _testlimitedcapi.set_discard
 | |
|         for cls in (set, set_subclass):
 | |
|             with self.subTest(cls=cls):
 | |
|                 instance = cls((1, 2))
 | |
|                 self.assertEqual(discard(instance, 3), 0)
 | |
|                 self.assertEqual(instance, {1, 2})
 | |
|                 self.assertEqual(discard(instance, 1), 1)
 | |
|                 self.assertEqual(instance, {2})
 | |
|                 self.assertEqual(discard(instance, 2), 1)
 | |
|                 self.assertEqual(instance, set())
 | |
|                 self.assertEqual(discard(instance, 2), 0)
 | |
|                 self.assertEqual(instance, set())
 | |
|                 with self.assertRaisesRegex(TypeError, "unhashable type: 'list'"):
 | |
|                     discard(instance, [])
 | |
|         with self.assertRaises(SystemError):
 | |
|             discard(object(), 1)
 | |
|         self.assertImmutable(discard, 1)
 | |
|         # CRASHES: discard(NULL, object())
 | |
|         # CRASHES: discard(instance, NULL)
 | |
|         # CRASHES: discard(NULL, NULL)
 | |
| 
 | |
|     def test_pop(self):
 | |
|         pop = _testlimitedcapi.set_pop
 | |
|         orig = (1, 2)
 | |
|         for cls in (set, set_subclass):
 | |
|             with self.subTest(cls=cls):
 | |
|                 instance = cls(orig)
 | |
|                 self.assertIn(pop(instance), orig)
 | |
|                 self.assertEqual(len(instance), 1)
 | |
|                 self.assertIn(pop(instance), orig)
 | |
|                 self.assertEqual(len(instance), 0)
 | |
|                 with self.assertRaises(KeyError):
 | |
|                     pop(instance)
 | |
|         with self.assertRaises(SystemError):
 | |
|             pop(object())
 | |
|         self.assertImmutable(pop)
 | |
|         # CRASHES: pop(NULL)
 | |
| 
 | |
|     def test_clear(self):
 | |
|         clear = _testlimitedcapi.set_clear
 | |
|         for cls in (set, set_subclass):
 | |
|             with self.subTest(cls=cls):
 | |
|                 instance = cls((1, 2))
 | |
|                 self.assertEqual(clear(instance), 0)
 | |
|                 self.assertEqual(instance, set())
 | |
|                 self.assertEqual(clear(instance), 0)
 | |
|                 self.assertEqual(instance, set())
 | |
|         with self.assertRaises(SystemError):
 | |
|             clear(object())
 | |
|         self.assertImmutable(clear)
 | |
|         # CRASHES: clear(NULL)
 | |
| 
 | |
| 
 | |
| class TestInternalCAPI(BaseSetTests, unittest.TestCase):
 | |
|     def test_set_update(self):
 | |
|         update = _testinternalcapi.set_update
 | |
|         for cls in (set, set_subclass):
 | |
|             for it in ('ab', ('a', 'b'), ['a', 'b'],
 | |
|                        set('ab'), set_subclass('ab'),
 | |
|                        frozenset('ab'), frozenset_subclass('ab')):
 | |
|                 with self.subTest(cls=cls, it=it):
 | |
|                     instance = cls()
 | |
|                     self.assertEqual(update(instance, it), 0)
 | |
|                     self.assertEqual(instance, {'a', 'b'})
 | |
|                     instance = cls(it)
 | |
|                     self.assertEqual(update(instance, it), 0)
 | |
|                     self.assertEqual(instance, {'a', 'b'})
 | |
|             with self.assertRaisesRegex(TypeError, 'object is not iterable'):
 | |
|                 update(cls(), 1)
 | |
|             with self.assertRaisesRegex(TypeError, "unhashable type: 'dict'"):
 | |
|                 update(cls(), [{}])
 | |
|         with self.assertRaises(SystemError):
 | |
|             update(object(), 'ab')
 | |
|         self.assertImmutable(update, 'ab')
 | |
|         # CRASHES: update(NULL, object())
 | |
|         # CRASHES: update(instance, NULL)
 | |
|         # CRASHES: update(NULL, NULL)
 | |
| 
 | |
|     def test_set_next_entry(self):
 | |
|         set_next = _testinternalcapi.set_next_entry
 | |
|         for cls in (set, set_subclass, frozenset, frozenset_subclass):
 | |
|             with self.subTest(cls=cls):
 | |
|                 instance = cls('abc')
 | |
|                 pos = 0
 | |
|                 items = []
 | |
|                 while True:
 | |
|                     res = set_next(instance, pos)
 | |
|                     if res is None:
 | |
|                         break
 | |
|                     rc, pos, hash_, item = res
 | |
|                     items.append(item)
 | |
|                     self.assertEqual(rc, 1)
 | |
|                     self.assertIn(item, instance)
 | |
|                     self.assertEqual(hash(item), hash_)
 | |
|                 self.assertEqual(items, list(instance))
 | |
|         with self.assertRaises(SystemError):
 | |
|             set_next(object(), 0)
 | |
|         # CRASHES: set_next(NULL, 0)
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     unittest.main()
 |