summaryrefslogtreecommitdiff
path: root/src/zope/interface/declarations.py
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2021-03-17 11:11:19 -0500
committerJason Madden <jamadden@gmail.com>2021-03-17 11:11:19 -0500
commit45b9294e9d3b8c679df0ae029de6b1792b183782 (patch)
treeaa91a2dbe549aa9ca1cd28920ef409af4c81f1f9 /src/zope/interface/declarations.py
parent762c253064dde6ee1ccd7b5ade7de7be357bf0b4 (diff)
downloadzope-interface-issue207.tar.gz
Make Provides and ClassProvides ignore redundant interfaces like @implementerissue207
cf #207
Diffstat (limited to 'src/zope/interface/declarations.py')
-rw-r--r--src/zope/interface/declarations.py17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/zope/interface/declarations.py b/src/zope/interface/declarations.py
index 9a0146c..d687599 100644
--- a/src/zope/interface/declarations.py
+++ b/src/zope/interface/declarations.py
@@ -131,6 +131,19 @@ class Declaration(Specification):
__radd__ = __add__
+ @staticmethod
+ def _add_interfaces_to_cls(interfaces, cls):
+ # Strip redundant interfaces already provided
+ # by the cls so we don't produce invalid
+ # resolution orders.
+ implemented_by_cls = implementedBy(cls)
+ interfaces = tuple([
+ iface
+ for iface in interfaces
+ if not implemented_by_cls.isOrExtends(iface)
+ ])
+ return interfaces + (implemented_by_cls,)
+
class _ImmutableDeclaration(Declaration):
# A Declaration that is immutable. Used as a singleton to
@@ -747,7 +760,7 @@ class Provides(Declaration): # Really named ProvidesClass
def __init__(self, cls, *interfaces):
self.__args = (cls, ) + interfaces
self._cls = cls
- Declaration.__init__(self, *(interfaces + (implementedBy(cls), )))
+ Declaration.__init__(self, *self._add_interfaces_to_cls(interfaces, cls))
def __repr__(self):
return "<%s.%s for %s>" % (
@@ -890,7 +903,7 @@ class ClassProvides(Declaration, ClassProvidesBase):
self._cls = cls
self._implements = implementedBy(cls)
self.__args = (cls, metacls, ) + interfaces
- Declaration.__init__(self, *(interfaces + (implementedBy(metacls), )))
+ Declaration.__init__(self, *self._add_interfaces_to_cls(interfaces, metacls))
def __repr__(self):
return "<%s.%s for %s>" % (