mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	 745c9d9dfc
			
		
	
	
		745c9d9dfc
		
			
		
	
	
	
	
		
			
			Fix typos in the Lib directory as identified by codespell. Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
		
			
				
	
	
		
			191 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
| Test implementation of the PEP 509: dictionary versioning.
 | |
| """
 | |
| import unittest
 | |
| from test.support import import_helper
 | |
| 
 | |
| # PEP 509 is implemented in CPython but other Python implementations
 | |
| # don't require to implement it
 | |
| _testcapi = import_helper.import_module('_testcapi')
 | |
| 
 | |
| 
 | |
| class DictVersionTests(unittest.TestCase):
 | |
|     type2test = dict
 | |
| 
 | |
|     def setUp(self):
 | |
|         self.seen_versions = set()
 | |
|         self.dict = None
 | |
| 
 | |
|     def check_version_unique(self, mydict):
 | |
|         version = _testcapi.dict_get_version(mydict)
 | |
|         self.assertNotIn(version, self.seen_versions)
 | |
|         self.seen_versions.add(version)
 | |
| 
 | |
|     def check_version_changed(self, mydict, method, *args, **kw):
 | |
|         result = method(*args, **kw)
 | |
|         self.check_version_unique(mydict)
 | |
|         return result
 | |
| 
 | |
|     def check_version_dont_change(self, mydict, method, *args, **kw):
 | |
|         version1 = _testcapi.dict_get_version(mydict)
 | |
|         self.seen_versions.add(version1)
 | |
| 
 | |
|         result = method(*args, **kw)
 | |
| 
 | |
|         version2 = _testcapi.dict_get_version(mydict)
 | |
|         self.assertEqual(version2, version1, "version changed")
 | |
| 
 | |
|         return  result
 | |
| 
 | |
|     def new_dict(self, *args, **kw):
 | |
|         d = self.type2test(*args, **kw)
 | |
|         self.check_version_unique(d)
 | |
|         return d
 | |
| 
 | |
|     def test_constructor(self):
 | |
|         # new empty dictionaries must all have an unique version
 | |
|         empty1 = self.new_dict()
 | |
|         empty2 = self.new_dict()
 | |
|         empty3 = self.new_dict()
 | |
| 
 | |
|         # non-empty dictionaries must also have an unique version
 | |
|         nonempty1 = self.new_dict(x='x')
 | |
|         nonempty2 = self.new_dict(x='x', y='y')
 | |
| 
 | |
|     def test_copy(self):
 | |
|         d = self.new_dict(a=1, b=2)
 | |
| 
 | |
|         d2 = self.check_version_dont_change(d, d.copy)
 | |
| 
 | |
|         # dict.copy() must create a dictionary with a new unique version
 | |
|         self.check_version_unique(d2)
 | |
| 
 | |
|     def test_setitem(self):
 | |
|         d = self.new_dict()
 | |
| 
 | |
|         # creating new keys must change the version
 | |
|         self.check_version_changed(d, d.__setitem__, 'x', 'x')
 | |
|         self.check_version_changed(d, d.__setitem__, 'y', 'y')
 | |
| 
 | |
|         # changing values must change the version
 | |
|         self.check_version_changed(d, d.__setitem__, 'x', 1)
 | |
|         self.check_version_changed(d, d.__setitem__, 'y', 2)
 | |
| 
 | |
|     def test_setitem_same_value(self):
 | |
|         value = object()
 | |
|         d = self.new_dict()
 | |
| 
 | |
|         # setting a key must change the version
 | |
|         self.check_version_changed(d, d.__setitem__, 'key', value)
 | |
| 
 | |
|         # setting a key to the same value with dict.__setitem__
 | |
|         # must change the version
 | |
|         self.check_version_dont_change(d, d.__setitem__, 'key', value)
 | |
| 
 | |
|         # setting a key to the same value with dict.update
 | |
|         # must change the version
 | |
|         self.check_version_dont_change(d, d.update, key=value)
 | |
| 
 | |
|         d2 = self.new_dict(key=value)
 | |
|         self.check_version_dont_change(d, d.update, d2)
 | |
| 
 | |
|     def test_setitem_equal(self):
 | |
|         class AlwaysEqual:
 | |
|             def __eq__(self, other):
 | |
|                 return True
 | |
| 
 | |
|         value1 = AlwaysEqual()
 | |
|         value2 = AlwaysEqual()
 | |
|         self.assertTrue(value1 == value2)
 | |
|         self.assertFalse(value1 != value2)
 | |
|         self.assertIsNot(value1, value2)
 | |
| 
 | |
|         d = self.new_dict()
 | |
|         self.check_version_changed(d, d.__setitem__, 'key', value1)
 | |
|         self.assertIs(d['key'], value1)
 | |
| 
 | |
|         # setting a key to a value equal to the current value
 | |
|         # with dict.__setitem__() must change the version
 | |
|         self.check_version_changed(d, d.__setitem__, 'key', value2)
 | |
|         self.assertIs(d['key'], value2)
 | |
| 
 | |
|         # setting a key to a value equal to the current value
 | |
|         # with dict.update() must change the version
 | |
|         self.check_version_changed(d, d.update, key=value1)
 | |
|         self.assertIs(d['key'], value1)
 | |
| 
 | |
|         d2 = self.new_dict(key=value2)
 | |
|         self.check_version_changed(d, d.update, d2)
 | |
|         self.assertIs(d['key'], value2)
 | |
| 
 | |
|     def test_setdefault(self):
 | |
|         d = self.new_dict()
 | |
| 
 | |
|         # setting a key with dict.setdefault() must change the version
 | |
|         self.check_version_changed(d, d.setdefault, 'key', 'value1')
 | |
| 
 | |
|         # don't change the version if the key already exists
 | |
|         self.check_version_dont_change(d, d.setdefault, 'key', 'value2')
 | |
| 
 | |
|     def test_delitem(self):
 | |
|         d = self.new_dict(key='value')
 | |
| 
 | |
|         # deleting a key with dict.__delitem__() must change the version
 | |
|         self.check_version_changed(d, d.__delitem__, 'key')
 | |
| 
 | |
|         # don't change the version if the key doesn't exist
 | |
|         self.check_version_dont_change(d, self.assertRaises, KeyError,
 | |
|                                        d.__delitem__, 'key')
 | |
| 
 | |
|     def test_pop(self):
 | |
|         d = self.new_dict(key='value')
 | |
| 
 | |
|         # pop() must change the version if the key exists
 | |
|         self.check_version_changed(d, d.pop, 'key')
 | |
| 
 | |
|         # pop() must not change the version if the key does not exist
 | |
|         self.check_version_dont_change(d, self.assertRaises, KeyError,
 | |
|                                        d.pop, 'key')
 | |
| 
 | |
|     def test_popitem(self):
 | |
|         d = self.new_dict(key='value')
 | |
| 
 | |
|         # popitem() must change the version if the dict is not empty
 | |
|         self.check_version_changed(d, d.popitem)
 | |
| 
 | |
|         # popitem() must not change the version if the dict is empty
 | |
|         self.check_version_dont_change(d, self.assertRaises, KeyError,
 | |
|                                        d.popitem)
 | |
| 
 | |
|     def test_update(self):
 | |
|         d = self.new_dict(key='value')
 | |
| 
 | |
|         # update() calling with no argument must not change the version
 | |
|         self.check_version_dont_change(d, d.update)
 | |
| 
 | |
|         # update() must change the version
 | |
|         self.check_version_changed(d, d.update, key='new value')
 | |
| 
 | |
|         d2 = self.new_dict(key='value 3')
 | |
|         self.check_version_changed(d, d.update, d2)
 | |
| 
 | |
|     def test_clear(self):
 | |
|         d = self.new_dict(key='value')
 | |
| 
 | |
|         # clear() must change the version if the dict is not empty
 | |
|         self.check_version_changed(d, d.clear)
 | |
| 
 | |
|         # clear() must not change the version if the dict is empty
 | |
|         self.check_version_dont_change(d, d.clear)
 | |
| 
 | |
| 
 | |
| class Dict(dict):
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class DictSubtypeVersionTests(DictVersionTests):
 | |
|     type2test = Dict
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     unittest.main()
 |