PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/test/test_dict_version.py

https://gitlab.com/unofficial-mirrors/cpython
Python | 186 lines | 100 code | 55 blank | 31 comment | 1 complexity | 2f5f08ccdf345c2601f24210e57cfe82 MD5 | raw file
  1. """
  2. Test implementation of the PEP 509: dictionary versionning.
  3. """
  4. import unittest
  5. from test import support
  6. # PEP 509 is implemented in CPython but other Python implementations
  7. # don't require to implement it
  8. _testcapi = support.import_module('_testcapi')
  9. class DictVersionTests(unittest.TestCase):
  10. type2test = dict
  11. def setUp(self):
  12. self.seen_versions = set()
  13. self.dict = None
  14. def check_version_unique(self, mydict):
  15. version = _testcapi.dict_get_version(mydict)
  16. self.assertNotIn(version, self.seen_versions)
  17. self.seen_versions.add(version)
  18. def check_version_changed(self, mydict, method, *args, **kw):
  19. result = method(*args, **kw)
  20. self.check_version_unique(mydict)
  21. return result
  22. def check_version_dont_change(self, mydict, method, *args, **kw):
  23. version1 = _testcapi.dict_get_version(mydict)
  24. self.seen_versions.add(version1)
  25. result = method(*args, **kw)
  26. version2 = _testcapi.dict_get_version(mydict)
  27. self.assertEqual(version2, version1, "version changed")
  28. return result
  29. def new_dict(self, *args, **kw):
  30. d = self.type2test(*args, **kw)
  31. self.check_version_unique(d)
  32. return d
  33. def test_constructor(self):
  34. # new empty dictionaries must all have an unique version
  35. empty1 = self.new_dict()
  36. empty2 = self.new_dict()
  37. empty3 = self.new_dict()
  38. # non-empty dictionaries must also have an unique version
  39. nonempty1 = self.new_dict(x='x')
  40. nonempty2 = self.new_dict(x='x', y='y')
  41. def test_copy(self):
  42. d = self.new_dict(a=1, b=2)
  43. d2 = self.check_version_dont_change(d, d.copy)
  44. # dict.copy() must create a dictionary with a new unique version
  45. self.check_version_unique(d2)
  46. def test_setitem(self):
  47. d = self.new_dict()
  48. # creating new keys must change the version
  49. self.check_version_changed(d, d.__setitem__, 'x', 'x')
  50. self.check_version_changed(d, d.__setitem__, 'y', 'y')
  51. # changing values must change the version
  52. self.check_version_changed(d, d.__setitem__, 'x', 1)
  53. self.check_version_changed(d, d.__setitem__, 'y', 2)
  54. def test_setitem_same_value(self):
  55. value = object()
  56. d = self.new_dict()
  57. # setting a key must change the version
  58. self.check_version_changed(d, d.__setitem__, 'key', value)
  59. # setting a key to the same value with dict.__setitem__
  60. # must change the version
  61. self.check_version_changed(d, d.__setitem__, 'key', value)
  62. # setting a key to the same value with dict.update
  63. # must change the version
  64. self.check_version_changed(d, d.update, key=value)
  65. d2 = self.new_dict(key=value)
  66. self.check_version_changed(d, d.update, d2)
  67. def test_setitem_equal(self):
  68. class AlwaysEqual:
  69. def __eq__(self, other):
  70. return True
  71. value1 = AlwaysEqual()
  72. value2 = AlwaysEqual()
  73. self.assertTrue(value1 == value2)
  74. self.assertFalse(value1 != value2)
  75. d = self.new_dict()
  76. self.check_version_changed(d, d.__setitem__, 'key', value1)
  77. # setting a key to a value equal to the current value
  78. # with dict.__setitem__() must change the version
  79. self.check_version_changed(d, d.__setitem__, 'key', value2)
  80. # setting a key to a value equal to the current value
  81. # with dict.update() must change the version
  82. self.check_version_changed(d, d.update, key=value1)
  83. d2 = self.new_dict(key=value2)
  84. self.check_version_changed(d, d.update, d2)
  85. def test_setdefault(self):
  86. d = self.new_dict()
  87. # setting a key with dict.setdefault() must change the version
  88. self.check_version_changed(d, d.setdefault, 'key', 'value1')
  89. # don't change the version if the key already exists
  90. self.check_version_dont_change(d, d.setdefault, 'key', 'value2')
  91. def test_delitem(self):
  92. d = self.new_dict(key='value')
  93. # deleting a key with dict.__delitem__() must change the version
  94. self.check_version_changed(d, d.__delitem__, 'key')
  95. # don't change the version if the key doesn't exist
  96. self.check_version_dont_change(d, self.assertRaises, KeyError,
  97. d.__delitem__, 'key')
  98. def test_pop(self):
  99. d = self.new_dict(key='value')
  100. # pop() must change the version if the key exists
  101. self.check_version_changed(d, d.pop, 'key')
  102. # pop() must not change the version if the key does not exist
  103. self.check_version_dont_change(d, self.assertRaises, KeyError,
  104. d.pop, 'key')
  105. def test_popitem(self):
  106. d = self.new_dict(key='value')
  107. # popitem() must change the version if the dict is not empty
  108. self.check_version_changed(d, d.popitem)
  109. # popitem() must not change the version if the dict is empty
  110. self.check_version_dont_change(d, self.assertRaises, KeyError,
  111. d.popitem)
  112. def test_update(self):
  113. d = self.new_dict(key='value')
  114. # update() calling with no argument must not change the version
  115. self.check_version_dont_change(d, d.update)
  116. # update() must change the version
  117. self.check_version_changed(d, d.update, key='new value')
  118. d2 = self.new_dict(key='value 3')
  119. self.check_version_changed(d, d.update, d2)
  120. def test_clear(self):
  121. d = self.new_dict(key='value')
  122. # clear() must change the version if the dict is not empty
  123. self.check_version_changed(d, d.clear)
  124. # clear() must not change the version if the dict is empty
  125. self.check_version_dont_change(d, d.clear)
  126. class Dict(dict):
  127. pass
  128. class DictSubtypeVersionTests(DictVersionTests):
  129. type2test = Dict
  130. if __name__ == "__main__":
  131. unittest.main()