======
Bridge
======

The ``Five.bridge`` module provides functionality to convert a Zope 2
interface into a Zope 3 one.  First we'll import all we know about
interfaces from the two generations:

  >>> from Interface import Interface as Z2_Interface
  >>> from Interface import Attribute as Z2_Attribute

  >>> from zope.interface import Interface as Z3_Interface
  >>> from zope.interface import Attribute as Z3_Attribute
  >>> from zope.interface.interface import Method as Z3_Method


An empty interface
------------------

  >>> class IEmpty(Z2_Interface):
  ...     pass

  >>> from Products.Five.bridge import fromZ2Interface
  >>> IEmptyConverted = fromZ2Interface(IEmpty)

  >>> Z3_Interface.isEqualOrExtendedBy(IEmptyConverted)
  True
  >>> len(IEmptyConverted.names())
  0


Bases
-----

  >>> class IBase(Z2_Interface):
  ...     pass
  >>> class IDerived(IBase):
  ...     pass
  >>> IBase.getBases() == (Z2_Interface,)
  True
  >>> IDerived.getBases() == (IBase,)
  True
  >>> IDerived.extends(IBase)
  1
  >>> IDerived.extends(IEmpty)
  0

  >>> IBaseConverted = fromZ2Interface(IBase)
  >>> IDerivedConverted = fromZ2Interface(IDerived)
  >>> IBaseConverted.getBases() == (Z3_Interface,)
  True
  >>> IDerivedConverted.getBases() == (IBaseConverted,)
  True
  >>> IDerivedConverted.extends(IBaseConverted)
  True
  >>> IDerivedConverted.extends(IEmptyConverted)
  False


Attributes
----------

  >>> class IAttributes(Z2_Interface):
  ...     one = Z2_Attribute('one', 'One attribute')
  ...     another = Z2_Attribute('another', 'Another attribute')

  >>> converted = fromZ2Interface(IAttributes)

  >>> Z3_Interface.isEqualOrExtendedBy(converted)
  True
  >>> len(converted.names())
  2
  >>> 'one' in converted.names()
  True
  >>> 'another' in converted.names()
  True

  >>> one = converted.getDescriptionFor('one')
  >>> isinstance(one, Z3_Attribute)
  True
  >>> one.getName()
  'one'
  >>> one.getDoc()
  'One attribute'

  >>> another = converted.getDescriptionFor('another')
  >>> isinstance(another, Z3_Attribute)
  True
  >>> another.getName() 
  'another'
  >>> another.getDoc()
  'Another attribute'


Methods
-------

  >>> class IMethods(Z2_Interface):
  ...     def one():
  ...         """One method."""
  ...     def another(arg1, arg2):
  ...         """Another method, taking arguments."""

  >>> converted = fromZ2Interface(IMethods)

  >>> Z3_Interface.isEqualOrExtendedBy(converted)
  True
  >>> len(converted.names())
  2
  >>> 'one' in converted.names()
  True
  >>> 'another' in converted.names()
  True

  >>> one = converted.getDescriptionFor('one')
  >>> isinstance(one, Z3_Method)
  True
  >>> one.getName()
  'one'
  >>> one.getDoc()
  'One method.'
  >>> one.getSignatureString()
  '()'

  >>> another = converted.getDescriptionFor('another')
  >>> isinstance(another, Z3_Method)
  True
  >>> another.getName()
  'another'
  >>> another.getDoc()
  'Another method, taking arguments.'
  >>> another.getSignatureString()
  '(arg1, arg2)'


Invalid parameters
------------------

  >>> fromZ2Interface(None)
  Traceback (most recent call last):
  ...
  ValueError: Not a Zope 2 interface!

  >>> fromZ2Interface(object())
  Traceback (most recent call last):
  ... 
  ValueError: Not a Zope 2 interface!

  >>> class IZ3_NotAllowed(Z3_Interface):
  ...     pass
  >>> fromZ2Interface(IZ3_NotAllowed)
  Traceback (most recent call last):
  ...
  ValueError: Not a Zope 2 interface!
