[Checkins] SVN: zope.interface/branches/elro-metaclass-resolution/src/zope/interface/ InterfaceClass metaclass resolution.

Laurence Rowe l at lrowe.co.uk
Sun May 1 17:53:16 EDT 2011


Log message for revision 121497:
  InterfaceClass metaclass resolution.

Changed:
  U   zope.interface/branches/elro-metaclass-resolution/src/zope/interface/interface.py
  U   zope.interface/branches/elro-metaclass-resolution/src/zope/interface/tests/test_interface.py

-=-
Modified: zope.interface/branches/elro-metaclass-resolution/src/zope/interface/interface.py
===================================================================
--- zope.interface/branches/elro-metaclass-resolution/src/zope/interface/interface.py	2011-05-01 21:52:36 UTC (rev 121496)
+++ zope.interface/branches/elro-metaclass-resolution/src/zope/interface/interface.py	2011-05-01 21:53:16 UTC (rev 121497)
@@ -433,6 +433,22 @@
     #
     #implements(IInterface)
 
+    def __new__(cls, name, bases=(), attrs=None, __doc__=None,
+                 __module__=None):
+        # Resolve metaclass in the same way as ``type``
+        for base in bases:
+            meta = type(base)
+            if issubclass(cls, meta):
+                continue
+            if issubclass(meta, cls):
+                cls = meta
+                continue
+            raise TypeError(
+                "Error when calling the metaclass bases\n    "
+                "metaclass conflict: the metaclass of a derived class must be "
+                "a (non-strict) subclass of the metaclasses of all its bases")
+        return object.__new__(cls)
+
     def __init__(self, name, bases=(), attrs=None, __doc__=None,
                  __module__=None):
 

Modified: zope.interface/branches/elro-metaclass-resolution/src/zope/interface/tests/test_interface.py
===================================================================
--- zope.interface/branches/elro-metaclass-resolution/src/zope/interface/tests/test_interface.py	2011-05-01 21:52:36 UTC (rev 121496)
+++ zope.interface/branches/elro-metaclass-resolution/src/zope/interface/tests/test_interface.py	2011-05-01 21:53:16 UTC (rev 121497)
@@ -413,7 +413,33 @@
     True
     """
 
+def test_subclassing_interfaceclass():
+    """
+As ``InterfaceClass`` does not derive from ``type`` the normal python rules
+for determining the metaclass of a class from it's bases are not applied and
+the. In order to support specialisation, ``InterfaceClass`` resolves the
+metclass itself in ``__new__``.
 
+    >>> from zope.interface import Interface
+    >>> from zope.interface.interface import InterfaceClass
+    >>> class SpecialClass(InterfaceClass): pass
+    ... 
+    >>> Special = SpecialClass('Special')
+    >>> class I(Interface):
+    ...     pass
+
+    >>> class S(Special):
+    ...     pass
+
+    >>> class Combined(I, S):
+    ...     pass
+
+    >>> isinstance(Combined, SpecialClass)
+    True
+    """
+
+
+
 def test_suite():
     suite = unittest.makeSuite(InterfaceTests)
     suite.addTest(doctest.DocTestSuite("zope.interface.interface"))



More information about the checkins mailing list