summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lotze <thomas@thomas-lotze.net>2018-05-16 11:55:32 +0200
committerThomas Lotze <thomas@thomas-lotze.net>2018-05-16 11:55:32 +0200
commita3edb1cb2d0eab5c706334b3be8127d36dad31ec (patch)
treeafa526cd76371db67d8262b35be5bc46f233f9fd
parent919388ca4e26346f1a4463e0fecc8ad2fd9f871b (diff)
downloadzope-schema-re36-fields-hashable.tar.gz
re #36: Make fields hashable in Python 3.re36-fields-hashable
This fix should be improved according to the comments for the next release that allows backwards incompatibilities in Python 2.
-rw-r--r--CHANGES.rst4
-rw-r--r--src/zope/schema/_bootstrapfields.py13
-rw-r--r--src/zope/schema/tests/test__bootstrapfields.py20
3 files changed, 36 insertions, 1 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index ddf13a4..2453bc3 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,7 +4,9 @@ Changes
4.5.1 (unreleased)
------------------
-- Nothing changed yet.
+- Make fields hashable in Python 3 (#36).
+ This fix should be improved according to the comments for the next release
+ that allows backwards incompatibilities in Python 2.
4.5.0 (2017-07-10)
diff --git a/src/zope/schema/_bootstrapfields.py b/src/zope/schema/_bootstrapfields.py
index 8d5e7dc..0f061e7 100644
--- a/src/zope/schema/_bootstrapfields.py
+++ b/src/zope/schema/_bootstrapfields.py
@@ -184,6 +184,19 @@ class Field(Attribute):
except StopValidation:
pass
+ def __hash__(self):
+ # See <https://github.com/zopefoundation/zope.schema/issues/36>.
+ # XXX Good solution that is backwards-incompatible, though:
+ # Depend on an immutable subset of the equality criteria used in
+ # __eq__ to ensure that instances comparing equal by value have equal
+ # hash values, which boils down to the field type alone.
+
+ # return hash(type(self))
+
+ # XXX Temporary solution to make fields hashable in Python 3 without
+ # breaking backwards compatibility in Python 2:
+ return id(self)
+
def __eq__(self, other):
# should be the same type
if type(self) != type(other):
diff --git a/src/zope/schema/tests/test__bootstrapfields.py b/src/zope/schema/tests/test__bootstrapfields.py
index b709ee2..3f04873 100644
--- a/src/zope/schema/tests/test__bootstrapfields.py
+++ b/src/zope/schema/tests/test__bootstrapfields.py
@@ -364,6 +364,26 @@ class FieldTests(unittest.TestCase):
field.set(inst, 'AFTER')
self.assertEqual(inst.extant, 'AFTER')
+ def test_is_hashable(self):
+ field = self._makeOne()
+ hash(field) # doesn't raise
+
+ # XXX See <https://github.com/zopefoundation/zope.schema/issues/36>.
+ # Test should work when the final hash implementation is used.
+ # def test_equal_instances_have_same_hash(self):
+ # field1 = self._makeOne()
+ # field2 = self._makeOne()
+ # assert field1 is not field2
+ # assert field1 == field2
+ # self.assertTrue(hash(field1) == hash(field2))
+
+ def test_hash_varies_across_unequal_instances(self):
+ field1 = self._makeOne(title=u'foo')
+ field2 = self._makeOne(title=u'bar')
+ assert field1 is not field2
+ assert field1 != field2
+ self.assertFalse(hash(field1) == hash(field2))
+
class ContainerTests(unittest.TestCase):