Package zope :: Package interface :: Package tests :: Module test_declarations
[show private | hide private]
[frames | no frames]

Module zope.interface.tests.test_declarations

Test the new API for making and checking interface declarations

$Id: test_declarations.py,v 1.2 2005/06/24 16:52:47 nyergler Exp $
Classes
A  
B  
C  
COnly  
COnly_old  
D  
I1  
I2  
I3  
I4  
I5  
Test  

Function Summary
  test_classImplement_on_deeply_nested_classes()
This test is in response to a bug found, which is why it's a bit contrived
  test_classProvides_before_implements()
Special descriptor for class __provides__ The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.
  test_declaration_get()
We can get definitions from a declaration:
  test_getting_spec_for_proxied_builtin_class()
In general, we should be able to get a spec for a proxied class if someone has declared or asked for a spec before.
  test_ObjectSpecification_Simple()
  test_ObjectSpecification_Simple_old_style()
  test_ObjectSpecification_Simple_w_only()
  test_pickle_provides_specs()
  test_signature_w_no_class_interfaces()
  test_suite()
  test_that_we_dont_inherit_class_provides()
  test_that_we_dont_inherit_provides_optimizations()
When we make a declaration for a class, we install a __provides__ descriptors that provides a default for instances that don't have instance-specific declarations:

Function Details

test_classImplement_on_deeply_nested_classes()

This test is in response to a bug found, which is why it's a bit contrived
>>> from zope.interface import *
>>> class B1(object):
...     pass
>>> class B2(B1):
...     pass
>>> class B3(B2):
...     pass
>>> class D(object):
...     implements()
>>> class S(B3, D):
...     implements()
This failed due to a bug in the code for finding __providedBy__ descriptors for old-style classes.

test_classProvides_before_implements()

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that
we can get declarations for objects without instance-specific
interfaces a bit quicker.

    For example::

      >>> from zope.interface import Interface
      >>> class IFooFactory(Interface):
      ...     pass
      >>> class IFoo(Interface):
      ...     pass
      >>> class C(object):
      ...     classProvides(IFooFactory)
      ...     implements(IFoo)
      >>> [i.getName() for i in C.__provides__]
      ['IFooFactory']

      >>> [i.getName() for i in C().__provides__]
      ['IFoo']

test_declaration_get()

We can get definitions from a declaration:
>>> import zope.interface
>>> class I1(zope.interface.Interface):
...    a11 = zope.interface.Attribute('a11')
...    a12 = zope.interface.Attribute('a12')
>>> class I2(zope.interface.Interface):
...    a21 = zope.interface.Attribute('a21')
...    a22 = zope.interface.Attribute('a22')
...    a12 = zope.interface.Attribute('a212')
>>> class I11(I1):
...    a11 = zope.interface.Attribute('a111')
>>> decl = Declaration(I11, I2)
>>> decl.get('a11') is I11.get('a11')
True

>>> decl.get('a12') is I1.get('a12')
True

>>> decl.get('a21') is I2.get('a21')
True

>>> decl.get('a22') is I2.get('a22')
True

>>> decl.get('a')
>>> decl.get('a', 42)
42
We get None even with no interfaces:
>>> decl = Declaration()
>>> decl.get('a11')
>>> decl.get('a11', 42)
42
We get new data if e change interface bases:
>>> decl.__bases__ = I11, I2
>>> decl.get('a11') is I11.get('a11')
True

test_getting_spec_for_proxied_builtin_class()

In general, we should be able to get a spec for a proxied class if someone has declared or asked for a spec before.

We don't want to depend on proxies in this (zope.interface) package, but we do want to work with proxies. Proxies have the effect that a class's __dict__ cannot be gotten. Further, for built-in classes, we can't save, and thus, cannot get, any class attributes. We'll emulate this by treating a plain object as a class:
>>> cls = object()
We'll create an implements specification:
>>> import zope.interface.declarations
>>> impl = zope.interface.declarations.Implements(I1, I2)
Now, we'll emulate a declaration for a built-in type by putting it in BuiltinImplementationSpecifications:
>>> zope.interface.declarations.BuiltinImplementationSpecifications[
...   cls] = impl
Now, we should be able to get it back:
>>> implementedBy(cls) is impl
True

test_ObjectSpecification_Simple()

>>> c = C()
>>> directlyProvides(c, I4)
>>> [i.__name__ for i in providedBy(c)]
['I4', 'I3', 'I1', 'I2']

test_ObjectSpecification_Simple_old_style()

>>> c = COnly_old()
>>> directlyProvides(c, I4)
>>> [i.__name__ for i in providedBy(c)]
['I4', 'I3']

test_ObjectSpecification_Simple_w_only()

>>> c = COnly()
>>> directlyProvides(c, I4)
>>> [i.__name__ for i in providedBy(c)]
['I4', 'I3']

test_pickle_provides_specs()

>>> from pickle import dumps, loads
>>> a = A()
>>> I2.providedBy(a)
0

>>> directlyProvides(a, I2)
>>> I2.providedBy(a)
1

>>> a2 = loads(dumps(a))
>>> I2.providedBy(a2)
1

test_signature_w_no_class_interfaces()

>>> from zope.interface import *
>>> class C(object):
...     pass
>>> c = C()
>>> list(providedBy(c))
[]
>>> class I(Interface):
...    pass
>>> directlyProvides(c, I)
>>> list(providedBy(c))  == list(directlyProvidedBy(c))
1

test_that_we_dont_inherit_class_provides()

>>> class X(object):
...     classProvides(I1)
>>> class Y(X):
...     pass
>>> [i.__name__ for i in X.__provides__]
['I1']

>>> Y.__provides__
Traceback (most recent call last):

...

AttributeError: __provides__

test_that_we_dont_inherit_provides_optimizations()

When we make a declaration for a class, we install a __provides__ descriptors that provides a default for instances that don't have instance-specific declarations:
>>> class A(object):
...     implements(I1)
>>> class B(object):
...     implements(I2)
>>> [i.__name__ for i in A().__provides__]
['I1']

>>> [i.__name__ for i in B().__provides__]
['I2']
But it's important that we don't use this for subclasses without declarations. This would cause incorrect results:
>>> class X(A, B):
...     pass
>>> X().__provides__
Traceback (most recent call last):

...

AttributeError: __provides__
However, if we "induce" a declaration, by calling implementedBy (even indirectly through providedBy):
>>> [i.__name__ for i in providedBy(X())]
['I1', 'I2']
then the optimization will work:
>>> [i.__name__ for i in X().__provides__]
['I1', 'I2']

Generated by Epydoc 2.1 on Fri Jun 24 12:01:24 2005 http://epydoc.sf.net