[Zope3-checkins] CVS: Zope3/src/zope/interface/tests - odd.py:1.1.2.1 test_odd_declarations.py:1.1.2.1
Jim Fulton
jim@zope.com
Sat, 3 May 2003 11:40:37 -0400
Update of /cvs-repository/Zope3/src/zope/interface/tests
In directory cvs.zope.org:/tmp/cvs-serv13110/tests
Added Files:
Tag: interfacegeddon2-branch
odd.py test_odd_declarations.py
Log Message:
Added some support for ExtensionClass instances.
Old style declarations like:
class C(ExtensionClass.Base):
__implements__ = IFoo
work.
Also:
class C(ExtensionClass.Base):
pass
classImplements(IFoo)
works.
But use of implements and classprovides will produce incorrect
behavior. I'll be able to fix this in the next iteration.
Note, however, that we need to disallow declarations of interface
declarations for ExtensionClasses themselves until ExtensionClass is
rewritten to support descriptors.
=== Added File Zope3/src/zope/interface/tests/odd.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Odd meta class that doesn't subclass type.
This is used for testing support for ExtensionClass in new interfaces.
>>> class A:
... __metaclass__ = MetaClass
... a = 1
...
>>> A.__name__
'A'
>>> A.__bases__
()
>>> class B:
... __metaclass__ = MetaClass
... b = 1
...
>>> class C(A, B): pass
...
>>> C.__name__
'C'
>>> int(C.__bases__ == (A, B))
1
>>> a = A()
>>> aa = A()
>>> a.a
1
>>> aa.a
1
>>> aa.a = 2
>>> a.a
1
>>> aa.a
2
>>> c = C()
>>> c.a
1
>>> c.b
1
>>> c.b = 2
>>> c.b
2
>>> C.c = 1
>>> c.c
1
>>> from types import ClassType
>>> int(isinstance(C, (type, ClassType)))
0
>>> int(C.__class__.__class__ is C.__class__)
1
$Id: odd.py,v 1.1.2.1 2003/05/03 15:40:37 jim Exp $
"""
# class OddClass is an odd meta class
class MetaMetaClass(type):
def __getattribute__(self, name):
if name == '__class__':
return self
return type.__getattribute__(self, name)
class MetaClass(object):
"""Odd classes
"""
__metaclass__ = MetaMetaClass
def __init__(self, name, bases, dict):
self.__name__ = name
self.__bases__ = bases
self.__dict__.update(dict)
def __call__(self):
return OddInstance(self)
def __getattr__(self, name):
for b in self.__bases__:
v = getattr(b, name, self)
if v is not self:
return v
raise AttributeError, name
def __repr__(self):
return "<odd class %s at %s>" % (self.__name__, hex(id(self)))
class OddInstance(object):
def __init__(self, cls):
self.__dict__['__class__'] = cls
def __getattribute__(self, name):
dict = object.__getattribute__(self, '__dict__')
if name == '__dict__':
return dict
v = dict.get(name, self)
if v is not self:
return v
return getattr(dict['__class__'], name)
def __setattr__(self, name, v):
self.__dict__[name] = v
def __delattr__(self, name):
del self.__dict__[name]
def __repr__(self):
return "<odd %s instance at %s>" % (
self.__class__.__name__, hex(id(self)))
# DocTest:
if __name__ == "__main__":
import doctest, __main__
doctest.testmod(__main__, isprivate=lambda *a: False)
=== Added File Zope3/src/zope/interface/tests/test_odd_declarations.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Test interface declarations against ExtensionClass-like classes.
These tests are to make sure we do something sane in the presense of
classic ExtensionClass classes and instances.
$Id: test_odd_declarations.py,v 1.1.2.1 2003/05/03 15:40:37 jim Exp $
"""
import unittest, odd
from zope.interface import Interface
from zope.interface import directlyProvides, providedBy, directlyProvidedBy
from zope.interface import classImplements, classImplementsOnly, implementedBy
class I1(Interface): pass
class I2(Interface): pass
class I3(Interface): pass
class I31(I3): pass
class I4(Interface): pass
class I5(Interface): pass
class Odd: __metaclass__ = odd.MetaClass
class B(Odd): __implements__ = I2
# XXX We are going to need more magic to make implements work with odd
# classes. This will work in the next iteration. For now, we'll use
# a different mechanism.
# from zope.interface import implements, classProvides
class A(Odd):
# implements(I1)
__implements__ = I1
class C(A, B):
pass
#implements(I31)
classImplements(C, I31)
class Test(unittest.TestCase):
def test_ObjectSpecification(self):
c = C()
directlyProvides(c, I4)
self.assertEqual([i.__name__ for i in providedBy(c)],
['I4', 'I31', 'I1', 'I2']
)
self.assertEqual([i.__name__ for i in providedBy(c).flattened()],
['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
)
self.assert_(I1 in providedBy(c))
self.failIf(I3 in providedBy(c))
self.assert_(providedBy(c).extends(I3))
self.assert_(providedBy(c).extends(I31))
self.failIf(providedBy(c).extends(I5))
class COnly(A, B):
# XXX implementsOnly(I31)
__implements__ = I31
class D(COnly):
# XXX implements(I5)
pass
classImplements(D, I5)
c = D()
directlyProvides(c, I4)
self.assertEqual([i.__name__ for i in providedBy(c)],
['I4', 'I5', 'I31'])
self.assertEqual([i.__name__ for i in providedBy(c).flattened()],
['I4', 'I5', 'I31', 'I3', 'Interface'])
self.failIf(I1 in providedBy(c))
self.failIf(I3 in providedBy(c))
self.assert_(providedBy(c).extends(I3))
self.failIf(providedBy(c).extends(I1))
self.assert_(providedBy(c).extends(I31))
self.assert_(providedBy(c).extends(I5))
class COnly(A, B): __implements__ = I31
class D(COnly):
# XXX implements(I5)
pass
classImplements(D, I5)
c = D()
directlyProvides(c, I4)
self.assertEqual([i.__name__ for i in providedBy(c)],
['I4', 'I5', 'I31'])
self.assertEqual([i.__name__ for i in providedBy(c).flattened()],
['I4', 'I5', 'I31', 'I3', 'Interface'])
self.failIf(I1 in providedBy(c))
self.failIf(I3 in providedBy(c))
self.assert_(providedBy(c).extends(I3))
self.failIf(providedBy(c).extends(I1))
self.assert_(providedBy(c).extends(I31))
self.assert_(providedBy(c).extends(I5))
def test_classImplements(self):
class A(Odd):
# XXX implements(I3)
__implements__ = I3
class B(Odd):
# XXX implements(I4)
__implements__ = I4
class C(A, B):
pass
classImplements(C, I1, I2)
self.assertEqual([i.__name__ for i in implementedBy(C)],
['I1', 'I2', 'I3', 'I4'])
classImplements(C, I5)
self.assertEqual([i.__name__ for i in implementedBy(C)],
['I1', 'I2', 'I5', 'I3', 'I4'])
def test_classImplementsOnly(self):
class A(Odd):
# XXX implements(I3)
__implements__ = I3
class B(Odd):
# XXX implements(I4)
__implements__ = I4
class C(A, B):
pass
classImplementsOnly(C, I1, I2)
self.assertEqual([i.__name__ for i in implementedBy(C)],
['I1', 'I2'])
def test_directlyProvides(self):
class IA1(Interface): pass
class IA2(Interface): pass
class IB(Interface): pass
class IC(Interface): pass
class A(Odd):
# XXX implements(IA1, IA2)
__implements__ = IA1, IA2
class B(Odd):
# XXX implements(IB)
__implements__ = IB
class C(A, B):
# XXX implements(IC)
pass
classImplements(C, IC)
ob = C()
directlyProvides(ob, I1, I2)
self.assert_(I1 in providedBy(ob))
self.assert_(I2 in providedBy(ob))
self.assert_(IA1 in providedBy(ob))
self.assert_(IA2 in providedBy(ob))
self.assert_(IB in providedBy(ob))
self.assert_(IC in providedBy(ob))
directlyProvides(ob, directlyProvidedBy(ob)-I2)
self.assert_(I1 in providedBy(ob))
self.failIf(I2 in providedBy(ob))
self.failIf(I2 in providedBy(ob))
directlyProvides(ob, directlyProvidedBy(ob), I2)
self.assert_(I2 in providedBy(ob))
def test_directlyProvides_fails_for_odd_class(self):
self.assertRaises(TypeError, directlyProvides, C, I5)
# XXX see above
def XXX_test_classProvides_fails_for_odd_class(self):
try:
class A(Odd):
classProvides(I1)
except TypeError:
pass # Sucess
self.assert_(False,
"Shouldn't be able to use directlyProvides on odd class."
)
def test_implementedBy(self):
class I2(I1): pass
class C1(Odd):
# XXX implements(I2)
__implements__ = I2
class C2(C1):
# XXX implements(I3)
pass
classImplements(C2, I3)
self.assertEqual([i.__name__ for i in implementedBy(C2)],
['I3', 'I2'])
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(Test))
return suite
if __name__ == '__main__':
unittest.main()