summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2020-01-27 09:31:30 -0600
committerJason Madden <jamadden@gmail.com>2020-01-27 09:31:30 -0600
commitf41ebfdb0b432fd99e1c44c0a1d7fd54a637bdf8 (patch)
treeb15c734c418a50d33d0957964dd962c61fe33db9
parentfec4a51b1ce8526de23c2558bfd26e253c4b6250 (diff)
downloadzope-interface-f41ebfdb0b432fd99e1c44c0a1d7fd54a637bdf8.tar.gz
Remove support for hashing uninitialized interfaces.issue157
Fixes #157
-rw-r--r--CHANGES.rst13
-rw-r--r--setup.py2
-rw-r--r--src/zope/interface/interface.py9
-rw-r--r--src/zope/interface/tests/test_interface.py12
4 files changed, 16 insertions, 20 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 77fecbd..1d6923c 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,7 +2,7 @@
Changes
=========
-4.8.0 (unreleased)
+5.0.0 (unreleased)
==================
- Support the ``PURE_PYTHON`` environment variable at runtime instead
@@ -33,11 +33,20 @@
- Likewise, tagged values are relatively rare, so don't allocate a
dictionary to hold them until they are used.
- Use ``__slots___`` or the C equivalent ``tp_members`` in more
- common places. See `PR 155 <https://github.com/zopefoundation/zope.interface/pull/155>`_.
+ common places. Note that this removes the ability to set arbitrary
+ instance variables on certain objects.
+ See `PR 155 <https://github.com/zopefoundation/zope.interface/pull/155>`_.
The changes in this release resulted in a 7% memory reduction after
loading about 6,000 modules that define about 2,200 interfaces.
+- Remove support for hashing uninitialized interfaces. This could only
+ be done by subclassing ``InterfaceClass``. This has generated a
+ warning since it was first added in 2011 (3.6.5). Please call the
+ ``InterfaceClass`` constructor or otherwise set the appropriate
+ fields in your subclass before attempting to hash or sort it. See
+ `issue 157 <https://github.com/zopefoundation/zope.interface/issues/157>`_.
+
4.7.1 (2019-11-11)
==================
diff --git a/setup.py b/setup.py
index d6d0e34..b5e87a8 100644
--- a/setup.py
+++ b/setup.py
@@ -95,7 +95,7 @@ long_description = (
)
setup(name='zope.interface',
- version='4.8.0.dev0',
+ version='5.0.0.dev0',
url='https://github.com/zopefoundation/zope.interface',
license='ZPL 2.1',
description='Interfaces for Python',
diff --git a/src/zope/interface/interface.py b/src/zope/interface/interface.py
index 106a60d..7fa56aa 100644
--- a/src/zope/interface/interface.py
+++ b/src/zope/interface/interface.py
@@ -17,7 +17,6 @@
import sys
from types import MethodType
from types import FunctionType
-import warnings
import weakref
from zope.interface._compat import _use_c_impl
@@ -579,7 +578,7 @@ class InterfaceClass(Element, InterfaceBase, Specification):
if other is None:
return -1
- n1 = (getattr(self, '__name__', ''), getattr(self, '__module__', ''))
+ n1 = (self.__name__, self.__module__)
n2 = (getattr(other, '__name__', ''), getattr(other, '__module__', ''))
# This spelling works under Python3, which doesn't have cmp().
@@ -589,11 +588,7 @@ class InterfaceClass(Element, InterfaceBase, Specification):
try:
return self._v_cached_hash
except AttributeError:
- try:
- self._v_cached_hash = hash((self.__name__, self.__module__))
- except AttributeError: # pragma: no cover
- warnings.warn('Hashing uninitialized InterfaceClass instance')
- return 1
+ self._v_cached_hash = hash((self.__name__, self.__module__))
return self._v_cached_hash
def __eq__(self, other):
diff --git a/src/zope/interface/tests/test_interface.py b/src/zope/interface/tests/test_interface.py
index f5a57b4..3bf26dc 100644
--- a/src/zope/interface/tests/test_interface.py
+++ b/src/zope/interface/tests/test_interface.py
@@ -834,20 +834,12 @@ class InterfaceClassTests(unittest.TestCase):
'zope.interface.tests.test_interface'))))
def test___hash___missing_required_attrs(self):
- import warnings
- from warnings import catch_warnings
-
class Derived(self._getTargetClass()):
def __init__(self):
pass # Don't call base class.
derived = Derived()
- with catch_warnings(record=True) as warned:
- warnings.simplefilter('always') # see LP #825249
- self.assertEqual(hash(derived), 1)
- self.assertEqual(len(warned), 1)
- self.assertTrue(warned[0].category is UserWarning)
- self.assertEqual(str(warned[0].message),
- 'Hashing uninitialized InterfaceClass instance')
+ with self.assertRaises(AttributeError):
+ hash(derived)
def test_comparison_with_None(self):
iface = self._makeOne()