[Checkins] SVN: zope.interface/trunk/ Merge tseaver-no_2to3 branch.

Tres Seaver cvs-admin at zope.org
Tue Apr 17 15:31:50 UTC 2012


Log message for revision 125152:
  Merge tseaver-no_2to3 branch.

Changed:
  _U  zope.interface/trunk/
  U   zope.interface/trunk/.bzrignore
  U   zope.interface/trunk/CHANGES.txt
  U   zope.interface/trunk/bootstrap.py
  D   zope.interface/trunk/build_ext_2.py
  D   zope.interface/trunk/build_ext_3.py
  U   zope.interface/trunk/docs/README.rst
  U   zope.interface/trunk/docs/README.ru.rst
  U   zope.interface/trunk/docs/adapter.rst
  A   zope.interface/trunk/docs/api.rst
  U   zope.interface/trunk/docs/conf.py
  U   zope.interface/trunk/docs/foodforthought.rst
  U   zope.interface/trunk/docs/human.rst
  U   zope.interface/trunk/docs/index.rst
  U   zope.interface/trunk/docs/verify.rst
  U   zope.interface/trunk/setup.py
  A   zope.interface/trunk/src/zope/interface/_compat.py
  U   zope.interface/trunk/src/zope/interface/adapter.py
  U   zope.interface/trunk/src/zope/interface/advice.py
  U   zope.interface/trunk/src/zope/interface/declarations.py
  U   zope.interface/trunk/src/zope/interface/document.py
  U   zope.interface/trunk/src/zope/interface/interface.py
  U   zope.interface/trunk/src/zope/interface/interfaces.py
  U   zope.interface/trunk/src/zope/interface/registry.py
  U   zope.interface/trunk/src/zope/interface/tests/test_adapter.py
  U   zope.interface/trunk/src/zope/interface/tests/test_advice.py
  U   zope.interface/trunk/src/zope/interface/tests/test_declarations.py
  U   zope.interface/trunk/src/zope/interface/tests/test_interface.py
  U   zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py
  U   zope.interface/trunk/src/zope/interface/tests/test_registry.py
  U   zope.interface/trunk/src/zope/interface/tests/test_verify.py
  U   zope.interface/trunk/src/zope/interface/verify.py
  U   zope.interface/trunk/tox.ini

-=-

Property changes on: zope.interface/trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /zope.interface/branches/tseaver-better_unittests:124748,124760

   + /zope.interface/branches/tseaver-no_2to3:124955-124957,124972-124983,124985-124990,125004,125007,125011
/zope.interface/branches/tseaver-better_unittests:124748,124760

Modified: svk:merge
   - 62d5b8a3-27da-0310-9561-8e5933582275:/zope.interface/branches/tseaver-better_unittests:124760

   + 62d5b8a3-27da-0310-9561-8e5933582275:/zope.interface/branches/tseaver-better_unittests:124760
62d5b8a3-27da-0310-9561-8e5933582275:/zope.interface/branches/tseaver-no_2to3:125011


Modified: zope.interface/trunk/.bzrignore
===================================================================
--- zope.interface/trunk/.bzrignore	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/.bzrignore	2012-04-17 15:31:46 UTC (rev 125152)
@@ -10,3 +10,5 @@
 include
 lib
 docs/_build
+__pycache__
+.tox

Modified: zope.interface/trunk/CHANGES.txt
===================================================================
--- zope.interface/trunk/CHANGES.txt	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/CHANGES.txt	2012-04-17 15:31:46 UTC (rev 125152)
@@ -4,6 +4,17 @@
 4.0.0a1 (unreleased)
 --------------------
 
+- Deprecated the "class advice" APIs from ``zope.interface.declarations``:
+  ``implements``, ``implementsOnly``, and ``classProvides``.  In their place,
+  prefer the equivalent class decorators: ``@implementer``,
+  ``@implementer_only``, and ``@provider``.  Code which uses the deprecated
+  APIs will not work as expected under Py3k.
+
+- Removed use of '2to3' and associated fixers when installing under Py3k.
+  The code is now in a "compatible subset" which supports Python 2.6, 2.7,
+  and 3.2, including PyPy 1.8 (the version compatible with the 2.7 language
+  spec).
+
 - Dropped explicit support for Python 2.4 / 2.5 / 3.1.
 
 - Added support for PyPy.

Modified: zope.interface/trunk/bootstrap.py
===================================================================
--- zope.interface/trunk/bootstrap.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/bootstrap.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -23,8 +23,8 @@
 tmpeggs = tempfile.mkdtemp()
 
 ez = {}
-exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
-                     ).read() in ez
+exec(urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read(), ez)
 ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
 
 import pkg_resources

Deleted: zope.interface/trunk/build_ext_2.py
===================================================================
--- zope.interface/trunk/build_ext_2.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/build_ext_2.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -1,38 +0,0 @@
-import sys
-from distutils.errors import (CCompilerError, DistutilsExecError, 
-                              DistutilsPlatformError)
-try:
-    from setuptools.command.build_ext import build_ext
-except ImportError:
-    from distutils.command.build_ext import build_ext
-    
-
-class optional_build_ext(build_ext):
-    """This class subclasses build_ext and allows
-       the building of C extensions to fail.
-    """
-    def run(self):
-        try:
-            build_ext.run(self)
-        
-        except DistutilsPlatformError, e:
-            self._unavailable(e)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        
-        except (CCompilerError, DistutilsExecError), e:
-            self._unavailable(e)
-
-    def _unavailable(self, e):
-        print >> sys.stderr, '*' * 80
-        print >> sys.stderr, """WARNING:
-
-        An optional code optimization (C extension) could not be compiled.
-
-        Optimizations for this package will not be available!"""
-        print >> sys.stderr
-        print >> sys.stderr, e
-        print >> sys.stderr, '*' * 80
-        
\ No newline at end of file

Deleted: zope.interface/trunk/build_ext_3.py
===================================================================
--- zope.interface/trunk/build_ext_3.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/build_ext_3.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -1,40 +0,0 @@
-import os
-import sys
-from distutils.errors import (CCompilerError, DistutilsExecError, 
-                              DistutilsPlatformError)
-try:
-    from setuptools.command.build_ext import build_ext
-    from pkg_resources import (normalize_path, working_set, 
-                               add_activation_listener, require)
-except ImportError:
-    raise RuntimeError("zope.interface requires Distribute under Python 3. "
-                       "See http://packages.python.org/distribute")
-
-class optional_build_ext(build_ext):
-    """This class subclasses build_ext and allows
-       the building of C extensions to fail.
-    """
-    def run(self):
-        try:
-            build_ext.run(self)
-        
-        except DistutilsPlatformError as e:
-            self._unavailable(e)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        
-        except (CCompilerError, DistutilsExecError) as e:
-            self._unavailable(e)
-
-    def _unavailable(self, e):
-        print('*' * 80, file=sys.stderr)
-        print("""WARNING:
-
-        An optional code optimization (C extension) could not be compiled.
-
-        Optimizations for this package will not be available!""", file=sys.stderr)
-        print(file=sys.stderr)
-        print(e, file=sys.stderr)
-        print('*' * 80, file=sys.stderr)

Modified: zope.interface/trunk/docs/README.rst
===================================================================
--- zope.interface/trunk/docs/README.rst	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/README.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -21,8 +21,10 @@
 Defining interfaces
 ===================
 
-Interfaces are defined using Python class statements::
+Interfaces are defined using Python class statements:
 
+.. doctest::
+
   >>> import zope.interface
   >>> class IFoo(zope.interface.Interface):
   ...    """Foo blah blah"""
@@ -36,25 +38,33 @@
 subclassed `zope.interface.Interface`, which is an ancestor interface for
 all interfaces, much as `object` is an ancestor of all new-style
 classes [#create]_.   The interface is not a class, it's an Interface,
-an instance of `InterfaceClass`::
+an instance of `InterfaceClass`:
 
+.. doctest::
+
   >>> type(IFoo)
   <class 'zope.interface.interface.InterfaceClass'>
 
-We can ask for the interface's documentation::
+We can ask for the interface's documentation:
 
+.. doctest::
+
   >>> IFoo.__doc__
   'Foo blah blah'
 
-and its name::
+and its name:
 
+.. doctest::
+
   >>> IFoo.__name__
   'IFoo'
 
-and even its module::
+and even its module:
 
+.. doctest::
+
   >>> IFoo.__module__
-  '__main__'
+  '__builtin__'
 
 The interface defined two attributes:
 
@@ -78,8 +88,10 @@
   methods that are not instance methods.
 
 You can access the attributes defined by an interface using mapping
-syntax::
+syntax:
 
+.. doctest::
+
   >>> x = IFoo['x']
   >>> type(x)
   <class 'zope.interface.interface.Attribute'>
@@ -93,28 +105,36 @@
 
   >>> IFoo.get('y')
 
-You can use `in` to determine if an interface defines a name::
+You can use `in` to determine if an interface defines a name:
 
+.. doctest::
+
   >>> 'x' in IFoo
   True
 
-You can iterate over interfaces to get the names they define::
+You can iterate over interfaces to get the names they define:
 
+.. doctest::
+
   >>> names = list(IFoo)
   >>> names.sort()
   >>> names
   ['bar', 'x']
 
 Remember that interfaces aren't classes. You can't access attribute
-definitions as attributes of interfaces::
+definitions as attributes of interfaces:
 
+.. doctest::
+
   >>> IFoo.x
   Traceback (most recent call last):
     File "<stdin>", line 1, in ?
   AttributeError: 'InterfaceClass' object has no attribute 'x'
 
-Methods provide access to the method signature::
+Methods provide access to the method signature:
 
+.. doctest::
+
   >>> bar = IFoo['bar']
   >>> bar.getSignatureString()
   '(q, r=None)'
@@ -156,8 +176,10 @@
 --------------------------------
 
 The most common way to declare interfaces is using the implements
-function in a class statement::
+function in a class statement:
 
+.. doctest::
+
   >>> class Foo:
   ...     zope.interface.implements(IFoo)
   ...
@@ -174,30 +196,40 @@
 In this example, we declared that `Foo` implements `IFoo`. This means
 that instances of `Foo` provide `IFoo`.  Having made this declaration,
 there are several ways we can introspect the declarations.  First, we
-can ask an interface whether it is implemented by a class::
+can ask an interface whether it is implemented by a class:
 
+.. doctest::
+
   >>> IFoo.implementedBy(Foo)
   True
 
-And we can ask whether an interface is provided by an object::
+And we can ask whether an interface is provided by an object:
 
+.. doctest::
+
   >>> foo = Foo()
   >>> IFoo.providedBy(foo)
   True
 
-Of course, `Foo` doesn't provide `IFoo`, it implements it::
+Of course, `Foo` doesn't provide `IFoo`, it implements it:
 
+.. doctest::
+
   >>> IFoo.providedBy(Foo)
   False
 
-We can also ask what interfaces are implemented by an object::
+We can also ask what interfaces are implemented by an object:
 
+.. doctest::
+
   >>> list(zope.interface.implementedBy(Foo))
-  [<InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.IFoo>]
 
 It's an error to ask for interfaces implemented by a non-callable
-object::
+object:
 
+.. doctest::
+
   >>> IFoo.implementedBy(foo)
   Traceback (most recent call last):
   ...
@@ -208,17 +240,21 @@
   ...
   TypeError: ('ImplementedBy called for non-factory', Foo(None))
 
-Similarly, we can ask what interfaces are provided by an object::
+Similarly, we can ask what interfaces are provided by an object:
 
+.. doctest::
+
   >>> list(zope.interface.providedBy(foo))
-  [<InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.IFoo>]
   >>> list(zope.interface.providedBy(Foo))
   []
 
 We can declare interfaces implemented by other factories (besides
 classes).  We do this using a Python-2.4-style decorator named
-`implementer`.  In versions of Python before 2.4, this looks like::
+`implementer`.  In versions of Python before 2.4, this looks like:
 
+.. doctest::
+
   >>> def yfoo(y):
   ...     foo = Foo()
   ...     foo.y = y
@@ -226,14 +262,16 @@
   >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
 
   >>> list(zope.interface.implementedBy(yfoo))
-  [<InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.IFoo>]
 
 Note that the implementer decorator may modify it's argument. Callers
 should not assume that a new object is created.
 
 Using implementer also works on callable objects. This is used by
-zope.formlib, as an example.
+zope.formlib, as an example:
 
+.. doctest::
+
   >>> class yfactory:
   ...     def __call__(self, y):
   ...         foo = Foo()
@@ -243,16 +281,18 @@
   >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
 
   >>> list(zope.interface.implementedBy(yfoo))
-  [<InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.IFoo>]
 
 XXX: Double check and update these version numbers:
 
 In zope.interface 3.5.2 and lower, the implementer decorator can not
 be used for classes, but in 3.6.0 and higher it can:
 
+.. doctest::
+
   >>> Foo = zope.interface.implementer(IFoo)(Foo)
   >>> list(zope.interface.providedBy(Foo()))
-  [<InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.IFoo>]
   
 Note that class decorators using the @implementer(IFoo) syntax are only 
 supported in Python 2.6 and later.
@@ -265,8 +305,10 @@
 we want to document what the `__init__` method of the `Foo` class
 does.  It's not *really* part of `IFoo`.  You wouldn't normally call
 the `__init__` method on Foo instances.  Rather, the `__init__` method
-is part of the `Foo`'s `__call__` method::
+is part of the `Foo`'s `__call__` method:
 
+.. doctest::
+
   >>> class IFooFactory(zope.interface.Interface):
   ...     """Create foos"""
   ...
@@ -277,21 +319,27 @@
   ...         """
 
 It's the class that provides this interface, so we declare the
-interface on the class::
+interface on the class:
 
+.. doctest::
+
   >>> zope.interface.directlyProvides(Foo, IFooFactory)
 
-And then, we'll see that Foo provides some interfaces::
+And then, we'll see that Foo provides some interfaces:
 
+.. doctest::
+
   >>> list(zope.interface.providedBy(Foo))
-  [<InterfaceClass __main__.IFooFactory>]
+  [<InterfaceClass __builtin__.IFooFactory>]
   >>> IFooFactory.providedBy(Foo)
   True
 
 Declaring class interfaces is common enough that there's a special
 declaration function for it, `classProvides`, that allows the
-declaration from within a class statement::
+declaration from within a class statement:
 
+.. doctest::
+
   >>> class Foo2:
   ...     zope.interface.implements(IFoo)
   ...     zope.interface.classProvides(IFooFactory)
@@ -306,7 +354,7 @@
   ...         return "Foo(%s)" % self.x
 
   >>> list(zope.interface.providedBy(Foo2))
-  [<InterfaceClass __main__.IFooFactory>]
+  [<InterfaceClass __builtin__.IFooFactory>]
   >>> IFooFactory.providedBy(Foo2)
   True
 
@@ -317,16 +365,20 @@
 
 Sometimes, we want to declare interfaces on instances, even though
 those instances get interfaces from their classes.  Suppose we create
-a new interface, `ISpecial`::
+a new interface, `ISpecial`:
 
+.. doctest::
+
   >>> class ISpecial(zope.interface.Interface):
   ...     reason = zope.interface.Attribute("Reason why we're special")
   ...     def brag():
   ...         "Brag about being special"
 
 We can make an existing foo instance special by providing `reason`
-and `brag` attributes::
+and `brag` attributes:
 
+.. doctest::
+
   >>> foo.reason = 'I just am'
   >>> def brag():
   ...      return "I'm special!"
@@ -336,21 +388,27 @@
   >>> foo.brag()
   "I'm special!"
 
-and by declaring the interface::
+and by declaring the interface:
 
+.. doctest::
+
   >>> zope.interface.directlyProvides(foo, ISpecial)
 
-then the new interface is included in the provided interfaces::
+then the new interface is included in the provided interfaces:
 
+.. doctest::
+
   >>> ISpecial.providedBy(foo)
   True
   >>> list(zope.interface.providedBy(foo))
-  [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.ISpecial>, <InterfaceClass __builtin__.IFoo>]
 
-We can find out what interfaces are directly provided by an object::
+We can find out what interfaces are directly provided by an object:
 
+.. doctest::
+
   >>> list(zope.interface.directlyProvidedBy(foo))
-  [<InterfaceClass __main__.ISpecial>]
+  [<InterfaceClass __builtin__.ISpecial>]
 
   >>> newfoo = Foo()
   >>> list(zope.interface.directlyProvidedBy(newfoo))
@@ -359,8 +417,10 @@
 Inherited declarations
 ----------------------
 
-Normally, declarations are inherited::
+Normally, declarations are inherited:
 
+.. doctest::
+
   >>> class SpecialFoo(Foo):
   ...     zope.interface.implements(ISpecial)
   ...     reason = 'I just am'
@@ -368,14 +428,16 @@
   ...         return "I'm special because %s" % self.reason
 
   >>> list(zope.interface.implementedBy(SpecialFoo))
-  [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.ISpecial>, <InterfaceClass __builtin__.IFoo>]
 
   >>> list(zope.interface.providedBy(SpecialFoo()))
-  [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.ISpecial>, <InterfaceClass __builtin__.IFoo>]
 
 Sometimes, you don't want to inherit declarations.  In that case, you
-can use `implementsOnly`, instead of `implements`::
+can use `implementsOnly`, instead of `implements`:
 
+.. doctest::
+
   >>> class Special(Foo):
   ...     zope.interface.implementsOnly(ISpecial)
   ...     reason = 'I just am'
@@ -383,10 +445,10 @@
   ...         return "I'm special because %s" % self.reason
 
   >>> list(zope.interface.implementedBy(Special))
-  [<InterfaceClass __main__.ISpecial>]
+  [<InterfaceClass __builtin__.ISpecial>]
 
   >>> list(zope.interface.providedBy(Special()))
-  [<InterfaceClass __main__.ISpecial>]
+  [<InterfaceClass __builtin__.ISpecial>]
 
 External declarations
 ---------------------
@@ -395,23 +457,27 @@
 definition. Sometimes, we may want to make declarations from outside
 the class definition. For example, we might want to declare interfaces
 for classes that we didn't write.  The function `classImplements` can
-be used for this purpose::
+be used for this purpose:
 
+.. doctest::
+
   >>> class C:
   ...     pass
 
   >>> zope.interface.classImplements(C, IFoo)
   >>> list(zope.interface.implementedBy(C))
-  [<InterfaceClass __main__.IFoo>]
+  [<InterfaceClass __builtin__.IFoo>]
 
-We can use `classImplementsOnly` to exclude inherited interfaces::
+We can use `classImplementsOnly` to exclude inherited interfaces:
 
+.. doctest::
+
   >>> class C(Foo):
   ...     pass
 
   >>> zope.interface.classImplementsOnly(C, ISpecial)
   >>> list(zope.interface.implementedBy(C))
-  [<InterfaceClass __main__.ISpecial>]
+  [<InterfaceClass __builtin__.ISpecial>]
 
 
 
@@ -419,16 +485,20 @@
 -------------------
 
 When we declare interfaces, we create *declaration* objects.  When we
-query declarations, declaration objects are returned::
+query declarations, declaration objects are returned:
 
+.. doctest::
+
   >>> type(zope.interface.implementedBy(Special))
   <class 'zope.interface.declarations.Implements'>
 
 Declaration objects and interface objects are similar in many ways. In
 fact, they share a common base class.  The important thing to realize
 about them is that they can be used where interfaces are expected in
-declarations. Here's a silly example::
+declarations. Here's a silly example:
 
+.. doctest::
+
   >>> class Special2(Foo):
   ...     zope.interface.implementsOnly(
   ...          zope.interface.implementedBy(Foo),
@@ -440,18 +510,22 @@
 
 The declaration here is almost the same as
 ``zope.interface.implements(ISpecial)``, except that the order of
-interfaces in the resulting declaration is different::
+interfaces in the resulting declaration is different:
 
+.. doctest::
+
   >>> list(zope.interface.implementedBy(Special2))
-  [<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.ISpecial>]
+  [<InterfaceClass __builtin__.IFoo>, <InterfaceClass __builtin__.ISpecial>]
 
 
 Interface Inheritance
 =====================
 
 Interfaces can extend other interfaces. They do this simply by listing
-the other interfaces as base interfaces::
+the other interfaces as base interfaces:
 
+.. doctest::
+
   >>> class IBlat(zope.interface.Interface):
   ...     """Blat blah blah"""
   ...
@@ -469,15 +543,17 @@
   ...
 
   >>> IBaz.__bases__
-  (<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.IBlat>)
+  (<InterfaceClass __builtin__.IFoo>, <InterfaceClass __builtin__.IBlat>)
 
   >>> names = list(IBaz)
   >>> names.sort()
   >>> names
   ['bar', 'eek', 'x', 'y']
 
-Note that `IBaz` overrides eek::
+Note that `IBaz` overrides eek:
 
+.. doctest::
+
   >>> IBlat['eek'].__doc__
   'eek blah blah'
   >>> IBaz['eek'].__doc__
@@ -487,20 +563,26 @@
 an interface, the extending interface should be compatible [#compat]_
 with the extended interfaces.
 
-We can ask whether one interface extends another::
+We can ask whether one interface extends another:
 
+.. doctest::
+
   >>> IBaz.extends(IFoo)
   True
   >>> IBlat.extends(IFoo)
   False
 
-Note that interfaces don't extend themselves::
+Note that interfaces don't extend themselves:
 
+.. doctest::
+
   >>> IBaz.extends(IBaz)
   False
 
-Sometimes we wish they did, but we can, instead use `isOrExtends`::
+Sometimes we wish they did, but we can, instead use `isOrExtends`:
 
+.. doctest::
+
   >>> IBaz.isOrExtends(IBaz)
   True
   >>> IBaz.isOrExtends(IFoo)
@@ -511,8 +593,10 @@
 When we iterate over an interface, we get all of the names it defines,
 including names defined by base interfaces. Sometimes, we want *just*
 the names defined by the interface directly. We bane use the `names`
-method for that::
+method for that:
 
+.. doctest::
+
   >>> list(IBaz.names())
   ['eek']
 
@@ -521,8 +605,10 @@
 
 An interface may override attribute definitions from base interfaces.
 If two base interfaces define the same attribute, the attribute is
-inherited from the most specific interface. For example, with::
+inherited from the most specific interface. For example, with:
 
+.. doctest::
+
   >>> class IBase(zope.interface.Interface):
   ...
   ...     def foo():
@@ -540,8 +626,10 @@
   ...     pass
 
 ISub's definition of foo is the one from IBase2, since IBase2 is more
-specific that IBase::
+specific that IBase:
 
+.. doctest::
+
   >>> ISub['foo'].__doc__
   'base2 foo doc'
 
@@ -549,8 +637,10 @@
 
 Sometimes, it's useful to ask whether an interface defines an
 attribute directly.  You can use the direct method to get a directly
-defined definitions::
+defined definitions:
 
+.. doctest::
+
   >>> IBase.direct('foo').__doc__
   'base foo doc'
 
@@ -562,14 +652,16 @@
 Interfaces and declarations are both special cases of specifications.
 What we described above for interface inheritance applies to both
 declarations and specifications.  Declarations actually extend the
-interfaces that they declare::
+interfaces that they declare:
 
+.. doctest::
+
   >>> class Baz(object):
   ...     zope.interface.implements(IBaz)
 
   >>> baz_implements = zope.interface.implementedBy(Baz)
   >>> baz_implements.__bases__
-  (<InterfaceClass __main__.IBaz>, <implementedBy ...object>)
+  (<InterfaceClass __builtin__.IBaz>, <implementedBy ...object>)
 
   >>> baz_implements.extends(IFoo)
   True
@@ -580,13 +672,16 @@
   True
 
 Specifications (interfaces and declarations) provide an `__sro__`
-that lists the specification and all of it's ancestors::
+that lists the specification and all of it's ancestors:
 
-  >>> baz_implements.__sro__
-  (<implementedBy __main__.Baz>,
-   <InterfaceClass __main__.IBaz>,
-   <InterfaceClass __main__.IFoo>,
-   <InterfaceClass __main__.IBlat>,
+.. doctest::
+
+  >>> from pprint import pprint
+  >>> pprint(baz_implements.__sro__)
+  (<implementedBy __builtin__.Baz>,
+   <InterfaceClass __builtin__.IBaz>,
+   <InterfaceClass __builtin__.IFoo>,
+   <InterfaceClass __builtin__.IBlat>,
    <InterfaceClass zope.interface.Interface>,
    <implementedBy ...object>)
 
@@ -596,8 +691,10 @@
 
 Interfaces and attribute descriptions support an extension mechanism,
 borrowed from UML, called "tagged values" that lets us store extra
-data::
+data:
 
+.. doctest::
+
   >>> IFoo.setTaggedValue('date-modified', '2004-04-01')
   >>> IFoo.setTaggedValue('author', 'Jim Fulton')
   >>> IFoo.getTaggedValue('date-modified')
@@ -611,18 +708,22 @@
   ['author', 'date-modified']
 
 Function attributes are converted to tagged values when method
-attribute definitions are created::
+attribute definitions are created:
 
+.. doctest::
+
   >>> class IBazFactory(zope.interface.Interface):
   ...     def __call__():
   ...         "create one"
   ...     __call__.return_type = IBaz
 
   >>> IBazFactory['__call__'].getTaggedValue('return_type')
-  <InterfaceClass __main__.IBaz>
+  <InterfaceClass __builtin__.IBaz>
 
-Tagged values can also be defined from within an interface definition::
+Tagged values can also be defined from within an interface definition:
 
+.. doctest::
+
   >>> class IWithTaggedValues(zope.interface.Interface):
   ...     zope.interface.taggedValue('squish', 'squash')
   >>> IWithTaggedValues.getTaggedValue('squish')
@@ -635,8 +736,10 @@
 provide them. These conditions are expressed using one or more
 invariants.  Invariants are callable objects that will be called with
 an object that provides an interface. An invariant raises an `Invalid`
-exception if the condition doesn't hold.  Here's an example::
+exception if the condition doesn't hold.  Here's an example:
 
+.. doctest::
+
   >>> class RangeError(zope.interface.Invalid):
   ...     """A range has invalid limits"""
   ...     def __repr__(self):
@@ -646,16 +749,20 @@
   ...     if ob.max < ob.min:
   ...         raise RangeError(ob)
 
-Given this invariant, we can use it in an interface definition::
+Given this invariant, we can use it in an interface definition:
 
+.. doctest::
+
   >>> class IRange(zope.interface.Interface):
   ...     min = zope.interface.Attribute("Lower bound")
   ...     max = zope.interface.Attribute("Upper bound")
   ...
   ...     zope.interface.invariant(range_invariant)
 
-Interfaces have a method for checking their invariants::
+Interfaces have a method for checking their invariants:
 
+.. doctest::
+
   >>> class Range(object):
   ...     zope.interface.implements(IRange)
   ...
@@ -675,8 +782,10 @@
 If you have multiple invariants, you may not want to stop checking
 after the first error.  If you pass a list to `validateInvariants`,
 then a single `Invalid` exception will be raised with the list of
-exceptions as it's argument::
+exceptions as it's argument:
 
+.. doctest::
+
   >>> from zope.interface.exceptions import Invalid
   >>> errors = []
   >>> try:
@@ -685,8 +794,10 @@
   ...     str(e)
   '[RangeError(Range(2, 1))]'
   
-And the list will be filled with the individual exceptions::
+And the list will be filled with the individual exceptions:
 
+.. doctest::
+
   >>> errors
   [RangeError(Range(2, 1))]
 
@@ -700,25 +811,31 @@
 
 The semantics are based on those of the PEP 246 adapt function.
 
-If an object cannot be adapted, then a TypeError is raised::
+If an object cannot be adapted, then a TypeError is raised:
 
+.. doctest::
+
   >>> class I(zope.interface.Interface):
   ...     pass
 
   >>> I(0)
   Traceback (most recent call last):
   ...
-  TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
+  TypeError: ('Could not adapt', 0, <InterfaceClass __builtin__.I>)
 
 
 
-unless an alternate value is provided as a second positional argument::
+unless an alternate value is provided as a second positional argument:
 
+.. doctest::
+
   >>> I(0, 'bob')
   'bob'
 
-If an object already implements the interface, then it will be returned::
+If an object already implements the interface, then it will be returned:
 
+.. doctest::
+
   >>> class C(object):
   ...     zope.interface.implements(I)
 
@@ -726,8 +843,10 @@
   >>> I(obj) is obj
   True
 
-If an object implements __conform__, then it will be used::
+If an object implements __conform__, then it will be used:
 
+.. doctest::
+
   >>> class C(object):
   ...     zope.interface.implements(I)
   ...     def __conform__(self, proto):
@@ -736,8 +855,10 @@
   >>> I(C())
   0
 
-Adapter hooks (see __adapt__) will also be used, if present::
+Adapter hooks (see __adapt__) will also be used, if present:
 
+.. doctest::
+
   >>> from zope.interface.interface import adapter_hooks
   >>> def adapt_0_to_42(iface, obj):
   ...     if obj == 0:
@@ -751,11 +872,13 @@
   >>> I(0)
   Traceback (most recent call last):
   ...
-  TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
+  TypeError: ('Could not adapt', 0, <InterfaceClass __builtin__.I>)
 
 __adapt__
 ---------
 
+.. doctest::
+
   >>> class I(zope.interface.Interface):
   ...     pass
 
@@ -767,12 +890,16 @@
 The adapt method is responsible for adapting an object to the
 reciever.
 
-The default version returns None::
+The default version returns None:
 
+.. doctest::
+
   >>> I.__adapt__(0)
 
-unless the object given provides the interface::
+unless the object given provides the interface:
 
+.. doctest::
+
   >>> class C(object):
   ...     zope.interface.implements(I)
 
@@ -783,8 +910,10 @@
 Adapter hooks can be provided (or removed) to provide custom
 adaptation. We'll install a silly hook that adapts 0 to 42.
 We install a hook by simply adding it to the adapter_hooks
-list::
+list:
 
+.. doctest::
+
   >>> from zope.interface.interface import adapter_hooks
   >>> def adapt_0_to_42(iface, obj):
   ...     if obj == 0:
@@ -797,8 +926,10 @@
 Hooks must either return an adapter, or None if no adapter can
 be found.
 
-Hooks can be uninstalled by removing them from the list::
+Hooks can be uninstalled by removing them from the list:
 
+.. doctest::
+
   >>> adapter_hooks.remove(adapt_0_to_42)
   >>> I.__adapt__(0)
 

Modified: zope.interface/trunk/docs/README.ru.rst
===================================================================
--- zope.interface/trunk/docs/README.ru.rst	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/README.ru.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -234,7 +234,7 @@
 XXX: Double check and update these version numbers, and translate to russian:
 
 In zope.interface 3.5.1 and lower, the implementer decorator can not
-be used for classes, but in 3.5.2 and higher it can:
+be used for classes, but in 3.5.2 and higher it can::
 
   >>> Foo = zope.interface.implementer(IFoo)(Foo)
   >>> list(zope.interface.providedBy(Foo()))
@@ -737,6 +737,8 @@
 __adapt__
 ---------
 
+::
+
   >>> class I(zope.interface.Interface):
   ...     pass
 

Modified: zope.interface/trunk/docs/adapter.rst
===================================================================
--- zope.interface/trunk/docs/adapter.rst	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/adapter.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -15,8 +15,10 @@
 Single Adapters
 ===============
 
-Let's look at a simple example, using a single required specification::
+Let's look at a simple example, using a single required specification:
 
+.. doctest::
+
   >>> from zope.interface.adapter import AdapterRegistry
   >>> import zope.interface
 
@@ -29,12 +31,16 @@
 
   >>> registry = AdapterRegistry()
 
-We'll register an object that depends on IR1 and "provides" IP2::
+We'll register an object that depends on IR1 and "provides" IP2:
 
+.. doctest::
+
   >>> registry.register([IR1], IP2, '', 12)
 
-Given the registration, we can look it up again::
+Given the registration, we can look it up again:
 
+.. doctest::
+
   >>> registry.lookup([IR1], IP2, '')
   12
 
@@ -46,15 +52,19 @@
 previously-registered value.
 
 If an object depends on a specification, it can be looked up with a
-specification that extends the specification that it depends on::
+specification that extends the specification that it depends on:
 
+.. doctest::
+
   >>> class IR2(IR1):
   ...     pass
   >>> registry.lookup([IR2], IP2, '')
   12
 
-We can use a class implementation specification to look up the object::
+We can use a class implementation specification to look up the object:
 
+.. doctest::
+
   >>> class C2:
   ...     zope.interface.implements(IR2)
 
@@ -63,54 +73,72 @@
 
 
 and it can be looked up for interfaces that its provided interface
-extends::
+extends:
 
+.. doctest::
+
   >>> registry.lookup([IR1], IP1, '')
   12
   >>> registry.lookup([IR2], IP1, '')
   12
 
 But if you require a specification that doesn't extend the specification the
-object depends on, you won't get anything::
+object depends on, you won't get anything:
 
+.. doctest::
+
   >>> registry.lookup([zope.interface.Interface], IP1, '')
 
-By the way, you can pass a default value to lookup::
+By the way, you can pass a default value to lookup:
 
+.. doctest::
+
   >>> registry.lookup([zope.interface.Interface], IP1, '', 42)
   42
 
 If you try to get an interface the object doesn't provide, you also
-won't get anything::
+won't get anything:
 
+.. doctest::
+
   >>> class IP3(IP2):
   ...     pass
   >>> registry.lookup([IR1], IP3, '')
 
-You also won't get anything if you use the wrong name::
+You also won't get anything if you use the wrong name:
 
+.. doctest::
+
   >>> registry.lookup([IR1], IP1, 'bob')
   >>> registry.register([IR1], IP2, 'bob', "Bob's 12")
   >>> registry.lookup([IR1], IP1, 'bob')
   "Bob's 12"
 
-You can leave the name off when doing a lookup::
+You can leave the name off when doing a lookup:
 
+.. doctest::
+
   >>> registry.lookup([IR1], IP1)
   12
 
-If we register an object that provides IP1::
+If we register an object that provides IP1:
 
+.. doctest::
+
   >>> registry.register([IR1], IP1, '', 11)
 
-then that object will be prefered over O(12)::
+then that object will be prefered over O(12):
 
+.. doctest::
+
   >>> registry.lookup([IR1], IP1, '')
   11
 
 Also, if we register an object for IR2, then that will be prefered
-when using IR2::
+when using IR2:
 
+.. doctest::
+
   >>> registry.register([IR2], IP1, '', 21)
   >>> registry.lookup([IR2], IP1, '')
   21
@@ -120,8 +148,10 @@
 
 We can ask if there is an adapter registered for a collection of
 interfaces. This is different than lookup, because it looks for an
-exact match.
+exact match:
 
+.. doctest::
+
   >>> print registry.registered([IR1], IP1)
   11
 
@@ -145,8 +175,10 @@
 -------
 
 Lookup of single adapters is common enough that there is a specialized
-version of lookup that takes a single required interface::
+version of lookup that takes a single required interface:
 
+.. doctest::
+
   >>> registry.lookup1(IR2, IP1, '')
   21
   >>> registry.lookup1(IR2, IP1)
@@ -159,8 +191,10 @@
 object that implements an interface is adapted to another object that
 supports a different interface.  The adapter registry supports the
 computation of adapters. In this case, we have to register adapter
-factories::
+factories:
 
+.. doctest::
+
    >>> class IR(zope.interface.Interface):
    ...     pass
 
@@ -175,8 +209,10 @@
   >>> registry.register([IR], IP1, '', Y)
 
 In this case, we registered a class as the factory. Now we can call
-`queryAdapter` to get the adapted object::
+`queryAdapter` to get the adapted object:
 
+.. doctest::
+
   >>> x = X()
   >>> y = registry.queryAdapter(x, IP1)
   >>> y.__class__.__name__
@@ -184,8 +220,10 @@
   >>> y.context is x
   True
 
-We can register and lookup by name too::
+We can register and lookup by name too:
 
+.. doctest::
+
   >>> class Y2(Y):
   ...     pass
 
@@ -199,8 +237,10 @@
 When the adapter factory produces `None`, then this is treated as if no
 adapter has been found. This allows us to prevent adaptation (when desired)
 and let the adapter factory determine whether adaptation is possible based on
-the state of the object being adapted.
+the state of the object being adapted:
 
+.. doctest::
+
   >>> def factory(context):
   ...     if context.name == 'object':
   ...         return 'adapter'
@@ -221,8 +261,10 @@
   'default'
 
 An alternate method that provides the same function as `queryAdapter()` is
-`adapter_hook()`::
+`adapter_hook()`:
 
+.. doctest::
+
   >>> y = registry.adapter_hook(IP1, x)
   >>> y.__class__.__name__
   'Y'
@@ -243,20 +285,26 @@
 ----------------
   
 Sometimes, you want to provide an adapter that will adapt anything.
-For that, provide None as the required interface::
+For that, provide None as the required interface:
 
+.. doctest::
+
   >>> registry.register([None], IP1, '', 1)
   
 then we can use that adapter for interfaces we don't have specific
-adapters for::
+adapters for:
 
+.. doctest::
+
   >>> class IQ(zope.interface.Interface):
   ...     pass
   >>> registry.lookup([IQ], IP1, '')
   1
 
-Of course, specific adapters are still used when applicable::
+Of course, specific adapters are still used when applicable:
 
+.. doctest::
+
   >>> registry.lookup([IR2], IP1, '')
   21
 
@@ -264,8 +312,10 @@
 --------------
 
 You can register adapters for class declarations, which is almost the
-same as registering them for a class::
+same as registering them for a class:
 
+.. doctest::
+
   >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', 'C21')
   >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
   'C21'
@@ -276,6 +326,8 @@
 At some point it was impossible to register dictionary-based adapters due a
 bug. Let's make sure this works now:
 
+.. doctest::
+
   >>> adapter = {}
   >>> registry.register((), IQ, '', adapter)
   >>> registry.lookup((), IQ, '') is adapter
@@ -284,8 +336,10 @@
 Unregistering
 -------------
 
-You can unregister by registering None, rather than an object::
+You can unregister by registering None, rather than an object:
 
+.. doctest::
+
   >>> registry.register([zope.interface.implementedBy(C2)], IP1, '', None)
   >>> registry.lookup([zope.interface.implementedBy(C2)], IP1, '')
   21
@@ -297,8 +351,10 @@
 Multi-adapters
 ==============
 
-You can adapt multiple specifications::
+You can adapt multiple specifications:
 
+.. doctest::
+
   >>> registry.register([IR1, IQ], IP2, '', '1q2')
   >>> registry.lookup([IR1, IQ], IP2, '')
   '1q2'
@@ -322,13 +378,17 @@
 Multi-adaptation
 ----------------
 
-You can adapt multiple objects::
+You can adapt multiple objects:
 
+.. doctest::
+
   >>> class Q:
   ...     zope.interface.implements(IQ)
 
-As with single adapters, we register a factory, which is often a class::
+As with single adapters, we register a factory, which is often a class:
 
+.. doctest::
+
   >>> class IM(zope.interface.Interface):
   ...     pass
   >>> class M:
@@ -337,8 +397,10 @@
   ...         self.x, self.q = x, q
   >>> registry.register([IR, IQ], IM, '', M)
 
-And then we can call `queryMultiAdapter` to compute an adapter::
+And then we can call `queryMultiAdapter` to compute an adapter:
 
+.. doctest::
+
   >>> q = Q()
   >>> m = registry.queryMultiAdapter((x, q), IM)
   >>> m.__class__.__name__
@@ -346,8 +408,10 @@
   >>> m.x is x and m.q is q
   True
 
-and, of course, we can use names::
+and, of course, we can use names:
 
+.. doctest::
+
   >>> class M2(M):
   ...     pass
   >>> registry.register([IR, IQ], IM, 'bob', M2)
@@ -361,8 +425,10 @@
 ----------------
 
 As with single adapters, you can define default adapters by specifying
-None for the *first* specification::
+None for the *first* specification:
 
+.. doctest::
+
   >>> registry.register([None, IQ], IP2, '', 'q2')
   >>> registry.lookup([IS, IQ], IP2, '')
   'q2'
@@ -370,8 +436,10 @@
 Null Adapters
 =============
 
-You can also adapt no specification::
+You can also adapt no specification:
 
+.. doctest::
+
   >>> registry.register([], IP2, '', 2)
   >>> registry.lookup([], IP2, '')
   2
@@ -382,21 +450,27 @@
 ----------------------
 
 Adapters are named. Sometimes, it's useful to get all of the named
-adapters for given interfaces::
+adapters for given interfaces:
 
+.. doctest::
+
   >>> adapters = list(registry.lookupAll([IR1], IP1))
   >>> adapters.sort()
   >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]
 
-This works for multi-adapters too::
+This works for multi-adapters too:
 
+.. doctest::
+
   >>> registry.register([IR1, IQ2], IP2, 'bob', '1q2 for bob')
   >>> adapters = list(registry.lookupAll([IR2, IQ2], IP1))
   >>> adapters.sort()
   >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]
 
-And even null adapters::
+And even null adapters:
 
+.. doctest::
+
   >>> registry.register([], IP2, 'bob', 3)
   >>> adapters = list(registry.lookupAll([], IP1))
   >>> adapters.sort()
@@ -409,16 +483,20 @@
 specification.  Sometimes, we want to get all of the objects that
 match some specification.  We use subscriptions for this.  We
 subscribe objects against specifications and then later find all of
-the subscribed objects::
+the subscribed objects:
 
+.. doctest::
+
   >>> registry.subscribe([IR1], IP2, 'sub12 1')
   >>> registry.subscriptions([IR1], IP2)
   ['sub12 1']
 
 Note that, unlike regular adapters, subscriptions are unnamed.
 
-You can have multiple subscribers for the same specification::
+You can have multiple subscribers for the same specification:
 
+.. doctest::
+
   >>> registry.subscribe([IR1], IP2, 'sub12 2')
   >>> registry.subscriptions([IR1], IP2)
   ['sub12 1', 'sub12 2']
@@ -426,8 +504,10 @@
 If subscribers are registered for the same required interfaces, they
 are returned in the order of definition.
 
-You can register subscribers for all specifications using None::
+You can register subscribers for all specifications using None:
 
+.. doctest::
+
   >>> registry.subscribe([None], IP1, 'sub_1')
   >>> registry.subscriptions([IR2], IP1)
   ['sub_1', 'sub12 1', 'sub12 2']
@@ -436,8 +516,10 @@
 for less general required interfaces are returned before subscribers
 for more general interfaces.
 
-Subscriptions may be combined over multiple compatible specifications::
+Subscriptions may be combined over multiple compatible specifications:
 
+.. doctest::
+
   >>> registry.subscriptions([IR2], IP1)
   ['sub_1', 'sub12 1', 'sub12 2']
   >>> registry.subscribe([IR1], IP1, 'sub11')
@@ -449,22 +531,28 @@
   >>> registry.subscriptions([IR2], IP2)
   ['sub12 1', 'sub12 2', 'sub22']
 
-Subscriptions can be on multiple specifications::
+Subscriptions can be on multiple specifications:
 
+.. doctest::
+
   >>> registry.subscribe([IR1, IQ], IP2, 'sub1q2')
   >>> registry.subscriptions([IR1, IQ], IP2)
   ['sub1q2']
   
 As with single subscriptions and non-subscription adapters, you can
-specify None for the first required interface, to specify a default::
+specify None for the first required interface, to specify a default:
 
+.. doctest::
+
   >>> registry.subscribe([None, IQ], IP2, 'sub_q2')
   >>> registry.subscriptions([IS, IQ], IP2)
   ['sub_q2']
   >>> registry.subscriptions([IR1, IQ], IP2)
   ['sub_q2', 'sub1q2']
 
-You can have subscriptions that are indepenent of any specifications::
+You can have subscriptions that are indepenent of any specifications:
+
+.. doctest::
   
   >>> list(registry.subscriptions([], IP1))
   []
@@ -482,8 +570,10 @@
 -------------------------
 
 We can unregister subscribers.  When unregistering a subscriber, we
-can unregister a specific subscriber::
+can unregister a specific subscriber:
 
+.. doctest::
+
   >>> registry.unsubscribe([IR1], IP1, 'sub11')
   >>> registry.subscriptions([IR1], IP1)
   ['sub_1', 'sub12 1', 'sub12 2']
@@ -491,6 +581,8 @@
 If we don't specify a value, then all subscribers matching the given
 interfaces will be unsubscribed:
 
+.. doctest::
+
   >>> registry.unsubscribe([IR1], IP2)
   >>> registry.subscriptions([IR1], IP1)
   ['sub_1']
@@ -501,8 +593,10 @@
 
 We normally register adapter factories, which then allow us to compute
 adapters, but with subscriptions, we get multiple adapters.  Here's an
-example of multiple-object subscribers::
+example of multiple-object subscribers:
 
+.. doctest::
+
   >>> registry.subscribe([IR, IQ], IM, M)
   >>> registry.subscribe([IR, IQ], IM, M2)
 
@@ -516,8 +610,10 @@
   >>> [(s.x is x and s.q is q) for s in subscribers]
   [True, True]
 
-adapter factory subcribers can't return None values::
+adapter factory subcribers can't return None values:
 
+.. doctest::
+
   >>> def M3(x, y):
   ...     return None
 
@@ -533,8 +629,10 @@
 output.  It returns None.  A handler is unlike adapters in that it does
 all of its work when the factory is called.
 
-To register a handler, simply provide None as the provided interface::
+To register a handler, simply provide None as the provided interface:
 
+.. doctest::
+
   >>> def handler(event):
   ...     print 'handler', event
 

Copied: zope.interface/trunk/docs/api.rst (from rev 125011, zope.interface/branches/tseaver-no_2to3/docs/api.rst)
===================================================================
--- zope.interface/trunk/docs/api.rst	                        (rev 0)
+++ zope.interface/trunk/docs/api.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -0,0 +1,1031 @@
+:mod:`zope.interface` API Documentation
+=======================================
+
+
+:class:`zope.interface.interface.Specification`
+-----------------------------------------------
+
+API
++++
+
+Specification objects implement the API defined by
+:class:`zope.interface.interfaces.ISpecification`:
+
+.. autointerface:: zope.interface.interfaces.ISpecification
+   :members:
+   :member-order: bysource
+
+
+Usage
++++++
+
+For example:
+
+.. doctest::
+
+   >>> from zope.interface.interface import Specification
+   >>> from zope.interface import Interface
+   >>> class I1(Interface):
+   ...     pass
+   >>> class I2(I1):
+   ...     pass
+   >>> class I3(I2):
+   ...     pass
+   >>> [i.__name__ for i in I1.__bases__]
+   ['Interface']
+   >>> [i.__name__ for i in I2.__bases__]
+   ['I1']
+   >>> I3.extends(I1)
+   True
+   >>> I2.__bases__ = (Interface, )
+   >>> [i.__name__ for i in I2.__bases__]
+   ['Interface']
+   >>> I3.extends(I1)
+   False
+
+Exmples for :meth:`Specification.providedBy`:
+
+.. doctest::
+
+   >>> from zope.interface import *
+   >>> class I1(Interface):
+   ...     pass
+   >>> class C(object):
+   ...     implements(I1)
+   >>> c = C()
+   >>> class X(object):
+   ...     pass
+   >>> x = X()
+   >>> I1.providedBy(x)
+   False
+   >>> I1.providedBy(C)
+   False
+   >>> I1.providedBy(c)
+   True
+   >>> directlyProvides(x, I1)
+   >>> I1.providedBy(x)
+   True
+   >>> directlyProvides(C, I1)
+   >>> I1.providedBy(C)
+   True
+
+Examples for :meth:`Specification.isOrExtends`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> from zope.interface.declarations import Declaration
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Declaration()
+   >>> int(spec.extends(Interface))
+   1
+   >>> spec = Declaration(I2)
+   >>> int(spec.extends(Interface))
+   1
+   >>> int(spec.extends(I1))
+   1
+   >>> int(spec.extends(I2))
+   1
+   >>> int(spec.extends(I3))
+   0
+   >>> int(spec.extends(I4))
+   0
+
+Examples for :meth:`Specification.interfaces`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Specification((I2, I3))
+   >>> spec = Specification((I4, spec))
+   >>> i = spec.interfaces()
+   >>> [x.getName() for x in i]
+   ['I4', 'I2', 'I3']
+   >>> list(i)
+   []
+
+Exmples for :meth:`Specification.extends`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> from zope.interface.declarations import Declaration
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Declaration()
+   >>> int(spec.extends(Interface))
+   1
+   >>> spec = Declaration(I2)
+   >>> int(spec.extends(Interface))
+   1
+   >>> int(spec.extends(I1))
+   1
+   >>> int(spec.extends(I2))
+   1
+   >>> int(spec.extends(I3))
+   0
+   >>> int(spec.extends(I4))
+   0
+   >>> I2.extends(I2)
+   False
+   >>> I2.extends(I2, False)
+   True
+   >>> I2.extends(I2, strict=False)
+   True
+
+
+:class:`zope.interface.interface.InterfaceClass`
+------------------------------------------------
+
+API
++++
+
+Specification objects implement the API defined by
+:class:`zope.interface.interfaces.IInterface`:
+
+.. autointerface:: zope.interface.interfaces.IInterface
+   :members:
+   :member-order: bysource
+
+
+Usage
++++++
+
+Exmples for :meth:`InterfaceClass.extends`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>>
+   >>> i = I1.interfaces()
+   >>> [x.getName() for x in i]
+   ['I1']
+   >>> list(i)
+   []
+
+
+:class:`zope.interface.declarations.Declaration`
+------------------------------------------------
+
+API
++++
+
+Specification objects implement the API defined by
+:class:`zope.interface.interfaces.IDeclaration`:
+
+.. autointerface:: zope.interface.interfaces.IDeclaration
+   :members:
+   :member-order: bysource
+
+
+Usage
++++++
+
+Exmples for :meth:`Declaration.__contains__`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Declaration(I2, I3)
+   >>> spec = Declaration(I4, spec)
+   >>> int(I1 in spec)
+   0
+   >>> int(I2 in spec)
+   1
+   >>> int(I3 in spec)
+   1
+   >>> int(I4 in spec)
+   1
+
+Exmples for :meth:`Declaration.__iter__`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Declaration(I2, I3)
+   >>> spec = Declaration(I4, spec)
+   >>> i = iter(spec)
+   >>> [x.getName() for x in i]
+   ['I4', 'I2', 'I3']
+   >>> list(i)
+   []
+
+Exmples for :meth:`Declaration.flattened`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Declaration(I2, I3)
+   >>> spec = Declaration(I4, spec)
+   >>> i = spec.flattened()
+   >>> [x.getName() for x in i]
+   ['I4', 'I2', 'I1', 'I3', 'Interface']
+   >>> list(i)
+   []
+
+Exmples for :meth:`Declaration.__sub__`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Declaration()
+   >>> [iface.getName() for iface in spec]
+   []
+   >>> spec -= I1
+   >>> [iface.getName() for iface in spec]
+   []
+   >>> spec -= Declaration(I1, I2)
+   >>> [iface.getName() for iface in spec]
+   []
+   >>> spec = Declaration(I2, I4)
+   >>> [iface.getName() for iface in spec]
+   ['I2', 'I4']
+   >>> [iface.getName() for iface in spec - I4]
+   ['I2']
+   >>> [iface.getName() for iface in spec - I1]
+   ['I4']
+   >>> [iface.getName() for iface
+   ...  in spec - Declaration(I3, I4)]
+   ['I2']
+
+Exmples for :meth:`Declaration.__add__`:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> spec = Declaration()
+   >>> [iface.getName() for iface in spec]
+   []
+   >>> [iface.getName() for iface in spec+I1]
+   ['I1']
+   >>> [iface.getName() for iface in I1+spec]
+   ['I1']
+   >>> spec2 = spec
+   >>> spec += I1
+   >>> [iface.getName() for iface in spec]
+   ['I1']
+   >>> [iface.getName() for iface in spec2]
+   []
+   >>> spec2 += Declaration(I3, I4)
+   >>> [iface.getName() for iface in spec2]
+   ['I3', 'I4']
+   >>> [iface.getName() for iface in spec+spec2]
+   ['I1', 'I3', 'I4']
+   >>> [iface.getName() for iface in spec2+spec]
+   ['I3', 'I4', 'I1']
+
+
+:func:`zope.interface.declarations.implementedBy`
+-------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.implementedByFallback
+
+
+Usage
++++++
+
+Consider the following example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(Interface): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(Interface): pass
+   ...
+   >>> class A(object):
+   ...   implements(I3)
+   >>> class B(object):
+   ...   implements(I4)
+   >>> class C(A, B):
+   ...   pass
+   >>> classImplementsOnly(C, I1, I2)
+   >>> [i.getName() for i in implementedBy(C)]
+   ['I1', 'I2']
+   
+Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
+whatever interfaces instances of ``A`` and ``B`` implement.
+
+Another example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(I1): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(I3): pass
+   ...
+   >>> class C1(object):
+   ...   implements(I2)
+   >>> class C2(C1):
+   ...   implements(I3)
+   >>> [i.getName() for i in implementedBy(C2)]
+   ['I3', 'I2']
+
+Really, any object should be able to receive a successful answer, even
+an instance:
+
+.. doctest::
+
+   >>> class Callable(object):
+   ...     def __call__(self):
+   ...         return self
+   >>> implementedBy(Callable())
+   <implementedBy __builtin__.?>
+
+Note that the name of the spec ends with a '?', because the `Callable`
+instance does not have a `__name__` attribute.
+
+This also manages storage of implementation specifications
+
+
+:func:`zope.interface.declarations.classImplementsOnly`
+-------------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.classImplementsOnly
+
+
+Usage
++++++
+
+Consider the following example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(Interface): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(Interface): pass
+   ...
+   >>> class A(object):
+   ...   implements(I3)
+   >>> class B(object):
+   ...   implements(I4)
+   >>> class C(A, B):
+   ...   pass
+   >>> classImplementsOnly(C, I1, I2)
+   >>> [i.getName() for i in implementedBy(C)]
+   ['I1', 'I2']
+   
+Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
+whatever interfaces instances of ``A`` and ``B`` implement.
+
+
+:func:`zope.interface.declarations.classImplements`
+---------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.classImplements
+
+
+Usage
++++++
+
+Consider the following example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(Interface): pass
+   ...
+   >>> class I3(Interface): pass
+   ...
+   >>> class I4(Interface): pass
+   ...
+   >>> class I5(Interface): pass
+   ...
+   >>> class A(object):
+   ...   implements(I3)
+   >>> class B(object):
+   ...   implements(I4)
+   >>> class C(A, B):
+   ...   pass
+   >>> classImplements(C, I1, I2)
+   >>> [i.getName() for i in implementedBy(C)]
+   ['I1', 'I2', 'I3', 'I4']
+   >>> classImplements(C, I5)
+   >>> [i.getName() for i in implementedBy(C)]
+   ['I1', 'I2', 'I5', 'I3', 'I4']
+
+Instances of ``C`` provide ``I1``, ``I2``, ``I5``, and whatever
+interfaces instances of ``A`` and ``B`` provide.
+
+
+:class:`zope.interface.declarations.implementer`
+------------------------------------------------
+
+API
++++
+
+.. autoclass:: zope.interface.declarations.implementer
+   :members:
+   :member-order: bysource
+
+
+:class:`zope.interface.declarations.implementer_only`
+-----------------------------------------------------
+
+API
++++
+
+.. autoclass:: zope.interface.declarations.implementer_only
+   :members:
+   :member-order: bysource
+
+
+:func:`zope.interface.declarations.implements`
+----------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.implements
+
+
+
+:func:`zope.interface.declarations.implementsOnly`
+--------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.implementsOnly
+
+
+
+:class:`zope.interface.declarations.ProvidesClass`
+--------------------------------------------------
+
+API
++++
+
+.. autoclass:: zope.interface.declarations.ProvidesClass
+   :members:
+   :member-order: bysource
+
+
+Usage
++++++
+
+Descriptor semantics (via ``Provides.__get__``):
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class IFooFactory(Interface): pass
+   ...
+   >>> class C(object):
+   ...   pass
+   >>> from zope.interface.declarations import ProvidesClass
+   >>> C.__provides__ = ProvidesClass(C, IFooFactory)
+   >>> [i.getName() for i in C.__provides__]
+   ['IFooFactory']
+   >>> getattr(C(), '__provides__', 0)
+   0
+
+
+
+:func:`zope.interface.declarations.Provides`
+--------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.Provides
+
+
+Usage
++++++
+
+In the examples below, we are going to make assertions about
+the size of the weakvalue dictionary.  For the assertions to be
+meaningful, we need to force garbage collection to make sure garbage
+objects are, indeed, removed from the system. Depending on how Python
+is run, we may need to make multiple calls to be sure.  We provide a
+collect function to help with this:
+
+.. doctest::
+
+   >>> import gc
+   >>> def collect():
+   ...     for i in range(4):
+   ...         gc.collect()
+   >>> collect()
+   >>> from zope.interface.declarations import InstanceDeclarations
+   >>> before = len(InstanceDeclarations)
+   >>> class C(object):
+   ...    pass
+   >>> from zope.interface import Interface
+   >>> class I(Interface):
+   ...    pass
+   >>> c1 = C()
+   >>> c2 = C()
+   >>> len(InstanceDeclarations) == before
+   True
+   >>> directlyProvides(c1, I)
+   >>> len(InstanceDeclarations) == before + 1
+   True
+   >>> directlyProvides(c2, I)
+   >>> len(InstanceDeclarations) == before + 1
+   True
+   >>> del c1
+   >>> collect()
+   >>> len(InstanceDeclarations) == before + 1
+   True
+   >>> del c2
+   >>> collect()
+   >>> len(InstanceDeclarations) == before
+   True
+
+
+:func:`zope.interface.declarations.directlyProvides`
+----------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.directlyProvides
+
+
+Usage
++++++
+
+Consider the following example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(Interface): pass
+   ...
+   >>> class IA1(Interface): pass
+   ...
+   >>> class IA2(Interface): pass
+   ...
+   >>> class IB(Interface): pass
+   ...
+   >>> class IC(Interface): pass
+   ...
+   >>> class A(object):
+   ...     implements(IA1, IA2)
+   >>> class B(object):
+   ...     implements(IB)
+   >>> class C(A, B):
+   ...    implements(IC)
+   >>> ob = C()
+   >>> directlyProvides(ob, I1, I2)
+   >>> int(I1 in providedBy(ob))
+   1
+   >>> int(I2 in providedBy(ob))
+   1
+   >>> int(IA1 in providedBy(ob))
+   1
+   >>> int(IA2 in providedBy(ob))
+   1
+   >>> int(IB in providedBy(ob))
+   1
+   >>> int(IC in providedBy(ob))
+   1
+
+The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
+instances have been declared for instances of ``C``.
+
+To remove directly provided interfaces, use ``directlyProvidedBy`` and
+subtract the unwanted interfaces. For example:
+
+.. doctest::
+
+   >>> directlyProvides(ob, directlyProvidedBy(ob)-I2)
+   >>> int(I1 in providedBy(ob))
+   1
+   >>> int(I2 in providedBy(ob))
+   0
+
+removes I2 from the interfaces directly provided by ``ob``. The object,
+``ob`` no longer directly provides ``I2``, although it might still
+provide ``I2`` if it's class implements ``I2``.
+
+To add directly provided interfaces, use ``directlyProvidedBy`` and
+include additional interfaces.  For example:
+
+.. doctest::
+
+   >>> int(I2 in providedBy(ob))
+   0
+   >>> directlyProvides(ob, directlyProvidedBy(ob), I2)
+   
+adds ``I2`` to the interfaces directly provided by ob:
+
+.. doctest::
+
+   >>> int(I2 in providedBy(ob))
+   1
+
+We need to avoid setting this attribute on meta classes that
+don't support descriptors.
+
+We can do away with this check when we get rid of the old EC
+
+
+:func:`zope.interface.declarations.alsoProvides`
+------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.alsoProvides
+
+
+Usage
++++++
+
+Consider the following example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(Interface): pass
+   ...
+   >>> class IA1(Interface): pass
+   ...
+   >>> class IA2(Interface): pass
+   ...
+   >>> class IB(Interface): pass
+   ...
+   >>> class IC(Interface): pass
+   ...
+   >>> class A(object):
+   ...     implements(IA1, IA2)
+   >>> class B(object):
+   ...     implements(IB)
+   >>> class C(A, B):
+   ...    implements(IC)
+   >>> ob = C()
+   >>> directlyProvides(ob, I1)
+   >>> int(I1 in providedBy(ob))
+   1
+   >>> int(I2 in providedBy(ob))
+   0
+   >>> int(IA1 in providedBy(ob))
+   1
+   >>> int(IA2 in providedBy(ob))
+   1
+   >>> int(IB in providedBy(ob))
+   1
+   >>> int(IC in providedBy(ob))
+   1
+   >>> alsoProvides(ob, I2)
+   >>> int(I1 in providedBy(ob))
+   1
+   >>> int(I2 in providedBy(ob))
+   1
+   >>> int(IA1 in providedBy(ob))
+   1
+   >>> int(IA2 in providedBy(ob))
+   1
+   >>> int(IB in providedBy(ob))
+   1
+   >>> int(IC in providedBy(ob))
+   1
+
+The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
+instances have been declared for instances of ``C``. Notice that the
+alsoProvides just extends the provided interfaces.
+
+
+:func:`zope.interface.declarations.noLongerProvides`
+----------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.noLongerProvides
+
+
+Usage
++++++
+
+Consider the following two interfaces:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class I1(Interface): pass
+   ...
+   >>> class I2(Interface): pass
+   ...
+
+``I1`` is provided through the class, ``I2`` is directly provided
+by the object:
+
+.. doctest::
+
+   >>> class C(object):
+   ...    implements(I1)
+   >>> c = C()
+   >>> alsoProvides(c, I2)
+   >>> I2.providedBy(c)
+   True
+
+Remove I2 from c again:
+
+.. doctest::
+
+   >>> noLongerProvides(c, I2)
+   >>> I2.providedBy(c)
+   False
+
+Removing an interface that is provided through the class is not possible:
+
+.. doctest::
+
+   >>> noLongerProvides(c, I1)
+   Traceback (most recent call last):
+   ...
+   ValueError: Can only remove directly provided interfaces.
+
+
+:func:`zope.interface.declarations.directlyProvidedBy`
+------------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.directlyProvidedBy
+
+
+:func:`zope.interface.declarations.classProvides`
+-------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.classProvides
+
+
+Usage
++++++
+
+For example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> from zope.interface.declarations import implementer
+   >>> class IFooFactory(Interface):
+   ...     pass
+   >>> class IFoo(Interface):
+   ...     pass
+   >>> @implementer(IFoo)
+   ... class C(object):
+   ...     classProvides(IFooFactory)
+   >>> [i.getName() for i in C.__provides__]
+   ['IFooFactory']
+   >>> [i.getName() for i in C().__provides__]
+   ['IFoo']
+
+Which is equivalent to:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class IFoo(Interface): pass
+   ...
+   >>> class IFooFactory(Interface): pass
+   ...
+   >>> @implementer(IFoo)
+   ... class C(object):
+   ...   pass
+   >>> directlyProvides(C, IFooFactory)
+   >>> [i.getName() for i in C.__providedBy__]
+   ['IFooFactory']
+   >>> [i.getName() for i in C().__providedBy__]
+   ['IFoo']
+
+
+:class:`zope.interface.declarations.provider`
+---------------------------------------------
+
+API
++++
+
+.. autoclass:: zope.interface.declarations.provider
+   :members:
+   :member-order: bysource
+
+
+:func:`zope.interface.declarations.moduleProvides`
+--------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.moduleProvides
+
+
+
+:func:`zope.interface.declarations.ObjectSpecification`
+-------------------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.ObjectSpecification
+
+
+Usage
++++++
+
+For example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> 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 A(object):
+   ...     implements(I1)
+   >>> class B(object): __implemented__ = I2
+   ...
+   >>> class C(A, B):
+   ...     implements(I31)
+   >>> c = C()
+   >>> directlyProvides(c, I4)
+   >>> [i.getName() for i in providedBy(c)]
+   ['I4', 'I31', 'I1', 'I2']
+   >>> [i.getName() for i in providedBy(c).flattened()]
+   ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
+   >>> int(I1 in providedBy(c))
+   1
+   >>> int(I3 in providedBy(c))
+   0
+   >>> int(providedBy(c).extends(I3))
+   1
+   >>> int(providedBy(c).extends(I31))
+   1
+   >>> int(providedBy(c).extends(I5))
+   0
+   >>> class COnly(A, B):
+   ...     implementsOnly(I31)
+   >>> class D(COnly):
+   ...     implements(I5)
+   >>> c = D()
+   >>> directlyProvides(c, I4)
+   >>> [i.getName() for i in providedBy(c)]
+   ['I4', 'I5', 'I31']
+   >>> [i.getName() for i in providedBy(c).flattened()]
+   ['I4', 'I5', 'I31', 'I3', 'Interface']
+   >>> int(I1 in providedBy(c))
+   0
+   >>> int(I3 in providedBy(c))
+   0
+   >>> int(providedBy(c).extends(I3))
+   1
+   >>> int(providedBy(c).extends(I1))
+   0
+   >>> int(providedBy(c).extends(I31))
+   1
+   >>> int(providedBy(c).extends(I5))
+   1
+
+
+:func:`zope.interface.declarations.providedBy`
+----------------------------------------------
+
+API
++++
+
+.. autofunction:: zope.interface.declarations.providedBy
+
+
+:class:`zope.interface.declarations.ObjectSpecificationDescriptor`
+------------------------------------------------------------------
+
+API
++++
+
+.. autoclass:: zope.interface.declarations.ObjectSpecificationDescriptor
+   :members:
+   :member-order: bysource
+
+Usage
++++++
+
+For example:
+
+.. doctest::
+
+   >>> from zope.interface import Interface
+   >>> class IFoo(Interface): pass
+   ...
+   >>> class IFooFactory(Interface): pass
+   ...
+   >>> @implementer(IFoo)
+   ... class C(object):
+   ...   classProvides(IFooFactory)
+   >>> [i.getName() for i in C.__providedBy__]
+   ['IFooFactory']
+   >>> [i.getName() for i in C().__providedBy__]
+   ['IFoo']
+
+Get an ObjectSpecification bound to either an instance or a class,
+depending on how we were accessed.
+

Modified: zope.interface/trunk/docs/conf.py
===================================================================
--- zope.interface/trunk/docs/conf.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/conf.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -25,7 +25,15 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode']
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.doctest',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.todo',
+    'sphinx.ext.ifconfig',
+    'sphinx.ext.viewcode',
+    'repoze.sphinx.autointerface',
+]
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
@@ -40,8 +48,8 @@
 master_doc = 'index'
 
 # General information about the project.
-project = u'zope.interface'
-copyright = u'2012, Zope Foundation contributors'
+project = 'zope.interface'
+copyright = '2012, Zope Foundation contributors'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -183,8 +191,8 @@
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'zopeinterface.tex', u'zope.interface Documentation',
-   u'Zope Foundation contributors', 'manual'),
+  ('index', 'zopeinterface.tex', 'zope.interface Documentation',
+   'Zope Foundation contributors', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -213,8 +221,8 @@
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    ('index', 'zopeinterface', u'zope.interface Documentation',
-     [u'Zope Foundation contributors'], 1)
+    ('index', 'zopeinterface', 'zope.interface Documentation',
+     ['Zope Foundation contributors'], 1)
 ]
 
 # If true, show URL addresses after external links.
@@ -227,8 +235,8 @@
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-  ('index', 'zopeinterface', u'zope.interface Documentation',
-   u'Zope Foundation contributors', 'zopeinterface', 'One line description of project.',
+  ('index', 'zopeinterface', 'zope.interface Documentation',
+   'Zope Foundation contributors', 'zopeinterface', 'One line description of project.',
    'Miscellaneous'),
 ]
 

Modified: zope.interface/trunk/docs/foodforthought.rst
===================================================================
--- zope.interface/trunk/docs/foodforthought.rst	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/foodforthought.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -3,8 +3,10 @@
 ================================
 
 
-This file gives more subscription examples using a cooking-based example::
+This file gives more subscription examples using a cooking-based example:
 
+.. doctest::
+
     >>> from zope.interface.adapter import AdapterRegistry
     >>> registry = AdapterRegistry()
 
@@ -19,8 +21,10 @@
     ...     pass
 
 Adapting to some other interface for which there is no
-subscription adapter returns an empty sequence::
+subscription adapter returns an empty sequence:
 
+.. doctest::
+
     >>> class IRecipe(zope.interface.Interface):
     ...     pass
     >>> class ISausages(IRecipe):
@@ -33,14 +37,18 @@
     >>> list(registry.subscriptions([IPoultry], IRecipe))
     []
 
-unless we define a subscription::
+unless we define a subscription:
 
+.. doctest::
+
     >>> registry.subscribe([IAnimal], ISausages, 'sausages')
     >>> list(registry.subscriptions([IPoultry], ISausages))
     ['sausages']
 
-And define another subscription adapter::
+And define another subscription adapter:
 
+.. doctest::
+
     >>> registry.subscribe([IPoultry], INoodles, 'noodles')
     >>> meals = list(registry.subscriptions([IPoultry], IRecipe))
     >>> meals.sort()
@@ -53,8 +61,10 @@
     >>> meals
     ['kfc', 'noodles', 'sausages']
 
-And the answer for poultry hasn't changed::
+And the answer for poultry hasn't changed:
 
+.. doctest::
+
     >>> meals = list(registry.subscriptions([IPoultry], IRecipe))
     >>> meals.sort()
     >>> meals

Modified: zope.interface/trunk/docs/human.rst
===================================================================
--- zope.interface/trunk/docs/human.rst	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/human.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -6,14 +6,18 @@
 adapter registry. It is intended to provide a concrete but narrow example on
 how to use interfaces and adapters outside of Zope 3.
 
-First we have to import the interface package::
+First we have to import the interface package:
 
+.. doctest::
+
   >>> import zope.interface
 
 We now develop an interface for our object, which is a simple file in this
 case. For now we simply support one attribute, the body, which contains the
-actual file contents::
+actual file contents:
 
+.. doctest::
+
   >>> class IFile(zope.interface.Interface):
   ...
   ...     body = zope.interface.Attribute('Contents of the file.')
@@ -22,8 +26,10 @@
 For statistical reasons we often want to know the size of a file. However, it
 would be clumsy to implement the size directly in the file object, since the
 size really represents meta-data. Thus we create another interface that
-provides the size of something::
+provides the size of something:
 
+.. doctest::
+
   >>> class ISize(zope.interface.Interface):
   ...
   ...     def getSize():
@@ -32,8 +38,10 @@
 
 Now we need to implement the file. It is essential that the object states
 that it implements the `IFile` interface. We also provide a default body
-value (just to make things simpler for this example)::
+value (just to make things simpler for this example):
 
+.. doctest::
+
   >>> class File(object):
   ...
   ...      zope.interface.implements(IFile)
@@ -52,8 +60,10 @@
 that is used to extract the size from. Also by convention the context is
 stored in an attribute named `context` on the adapter. The twisted community
 refers to the context as the `original` object. However, you may feel free to
-use a specific argument name, such as `file`::
+use a specific argument name, such as `file`:
 
+.. doctest::
+
   >>> class FileSize(object):
   ...
   ...      zope.interface.implements(ISize)
@@ -68,8 +78,10 @@
 
 Now that we have written our adapter, we have to register it with an adapter
 registry, so that it can be looked up when needed. There is no such thing as a
-global registry; thus we have to instantiate one for our example manually::
+global registry; thus we have to instantiate one for our example manually:
 
+.. doctest::
+
   >>> from zope.interface.adapter import AdapterRegistry
   >>> registry = AdapterRegistry()
 
@@ -88,19 +100,25 @@
 `ISize`. The third argument is the name of the adapter. Since we do not care
 about names, we simply leave it as an empty string. Names are commonly useful,
 if you have adapters for the same set of interfaces, but they are useful in
-different situations. The last argument is simply the adapter class::
+different situations. The last argument is simply the adapter class:
 
+.. doctest::
+
   >>> registry.register([IFile], ISize, '', FileSize)
 
-You can now use the the registry to lookup the adapter::
+You can now use the the registry to lookup the adapter:
 
+.. doctest::
+
   >>> registry.lookup1(IFile, ISize, '')
-  <class '__main__.FileSize'>
+  <class 'FileSize'>
 
 Let's get a little bit more practical. Let's create a `File` instance and
 create the adapter using a registry lookup. Then we see whether the adapter
-returns the correct size by calling `getSize()`::
+returns the correct size by calling `getSize()`:
 
+.. doctest::
+
   >>> file = File()
   >>> size = registry.lookup1(IFile, ISize, '')(file)
   >>> size.getSize()
@@ -120,28 +138,36 @@
 used an adapter cache or persistent adapters, for instance. The helper hook is
 required to expect as first argument the desired output interface (for us
 `ISize`) and as the second argument the context of the adapter (here
-`file`). The function returns an adapter, i.e. a `FileSize` instance::
+`file`). The function returns an adapter, i.e. a `FileSize` instance:
 
+.. doctest::
+
   >>> def hook(provided, object):
   ...     adapter = registry.lookup1(zope.interface.providedBy(object),
   ...                                provided, '')
   ...     return adapter(object)
   ...
 
-We now just add the hook to an `adapter_hooks` list::
+We now just add the hook to an `adapter_hooks` list:
 
+.. doctest::
+
   >>> from zope.interface.interface import adapter_hooks
   >>> adapter_hooks.append(hook)
 
-Once the hook is registered, you can use the desired syntax::
+Once the hook is registered, you can use the desired syntax:
 
+.. doctest::
+
   >>> size = ISize(file)
   >>> size.getSize()
   7
 
 Now we have to cleanup after ourselves, so that others after us have a clean
-`adapter_hooks` list::
+`adapter_hooks` list:
 
+.. doctest::
+
   >>> adapter_hooks.remove(hook)
 
 That's it. I have intentionally left out a discussion of named adapters and

Modified: zope.interface/trunk/docs/index.rst
===================================================================
--- zope.interface/trunk/docs/index.rst	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/index.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -16,6 +16,7 @@
    human
    verify
    foodforthought
+   api
    hacking
 
 По-русски

Modified: zope.interface/trunk/docs/verify.rst
===================================================================
--- zope.interface/trunk/docs/verify.rst	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/docs/verify.rst	2012-04-17 15:31:46 UTC (rev 125152)
@@ -34,94 +34,97 @@
 Attributes of the object, be they defined by its class or added by its
 ``__init__`` method, will be recognized:
 
->>> from zope.interface import Interface, Attribute, implements
->>> from zope.interface.exceptions import BrokenImplementation
->>> class IFoo(Interface):
-...     x = Attribute("The X attribute")
-...     y = Attribute("The Y attribute")
+.. doctest::
 
->>> class Foo(object):
-...     implements(IFoo)
-...     x = 1
-...     def __init__(self):
-...         self.y = 2
+   >>> from zope.interface import Interface, Attribute, implements
+   >>> from zope.interface.exceptions import BrokenImplementation
+   >>> class IFoo(Interface):
+   ...     x = Attribute("The X attribute")
+   ...     y = Attribute("The Y attribute")
 
->>> from zope.interface.verify import verifyObject
->>> verifyObject(IFoo, Foo())
-True
+   >>> class Foo(object):
+   ...     implements(IFoo)
+   ...     x = 1
+   ...     def __init__(self):
+   ...         self.y = 2
 
+   >>> from zope.interface.verify import verifyObject
+   >>> verifyObject(IFoo, Foo())
+   True
+
 If either attribute is missing, verification will fail:
 
->>> class Foo(object):
-...     implements(IFoo)
-...     x = 1
+.. doctest::
 
->>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-...     verifyObject(IFoo, Foo())
-... except BrokenImplementation, e:
-...     print str(e)
-An object has failed to implement interface <InterfaceClass ...IFoo>
-<BLANKLINE>
-        The y attribute was not provided.
-<BLANKLINE>
+   >>> class Foo(object):
+   ...     implements(IFoo)
+   ...     x = 1
+   >>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+   ...     verifyObject(IFoo, Foo())
+   ... except BrokenImplementation, e:
+   ...     print str(e)
+   An object has failed to implement interface <InterfaceClass ...IFoo>
+   <BLANKLINE>
+           The y attribute was not provided.
+   <BLANKLINE>
+   >>> class Foo(object):
+   ...     implements(IFoo)
+   ...     def __init__(self):
+   ...         self.y = 2
+   >>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+   ...     verifyObject(IFoo, Foo())
+   ... except BrokenImplementation, e:
+   ...     print str(e)
+   An object has failed to implement interface <InterfaceClass ...IFoo>
+   <BLANKLINE>
+           The x attribute was not provided.
+   <BLANKLINE>
 
->>> class Foo(object):
-...     implements(IFoo)
-...     def __init__(self):
-...         self.y = 2
-
->>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-...     verifyObject(IFoo, Foo())
-... except BrokenImplementation, e:
-...     print str(e)
-An object has failed to implement interface <InterfaceClass ...IFoo>
-<BLANKLINE>
-        The x attribute was not provided.
-<BLANKLINE>
-
 If an attribute is implemented as a property that raises an AttributeError
 when trying to get its value, the attribute is considered missing:
 
->>> class IFoo(Interface):
-...     x = Attribute('The X attribute')
+.. doctest::
 
->>> class Foo(object):
-...     implements(IFoo)
-...     @property
-...     def x(self):
-...         raise AttributeError
+   >>> class IFoo(Interface):
+   ...     x = Attribute('The X attribute')
+   >>> class Foo(object):
+   ...     implements(IFoo)
+   ...     @property
+   ...     def x(self):
+   ...         raise AttributeError
+   >>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+   ...     verifyObject(IFoo, Foo())
+   ... except BrokenImplementation, e:
+   ...     print str(e)
+   An object has failed to implement interface <InterfaceClass ...IFoo>
+   <BLANKLINE>
+           The x attribute was not provided.
+   <BLANKLINE>
 
->>> try: #doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-...     verifyObject(IFoo, Foo())
-... except BrokenImplementation, e:
-...     print str(e)
-An object has failed to implement interface <InterfaceClass ...IFoo>
-<BLANKLINE>
-        The x attribute was not provided.
-<BLANKLINE>
-
 Any other exception raised by a property will propagate to the caller of
 ``verifyObject``:
 
->>> class Foo(object):
-...     implements(IFoo)
-...     @property
-...     def x(self):
-...         raise Exception
+.. doctest::
 
->>> verifyObject(IFoo, Foo())
-Traceback (most recent call last):
-Exception
+   >>> class Foo(object):
+   ...     implements(IFoo)
+   ...     @property
+   ...     def x(self):
+   ...         raise Exception
+   >>> verifyObject(IFoo, Foo())
+   Traceback (most recent call last):
+   Exception
 
 Of course, broken properties that are not required by the interface don't do
 any harm:
 
->>> class Foo(object):
-...     implements(IFoo)
-...     x = 1
-...     @property
-...     def y(self):
-...         raise Exception
+.. doctest::
 
->>> verifyObject(IFoo, Foo())
-True
+   >>> class Foo(object):
+   ...     implements(IFoo)
+   ...     x = 1
+   ...     @property
+   ...     def y(self):
+   ...         raise Exception
+   >>> verifyObject(IFoo, Foo())
+   True

Modified: zope.interface/trunk/setup.py
===================================================================
--- zope.interface/trunk/setup.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/setup.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -23,7 +23,43 @@
 import platform
 import sys
 
+from distutils.errors import CCompilerError
+from distutils.errors import DistutilsExecError
+from distutils.errors import DistutilsPlatformError
+
 try:
+    from setuptools.command.build_ext import build_ext
+except ImportError:
+    from distutils.command.build_ext import build_ext
+
+class optional_build_ext(build_ext):
+    """This class subclasses build_ext and allows
+       the building of C extensions to fail.
+    """
+    def run(self):
+        try:
+            build_ext.run(self)
+        except DistutilsPlatformError as e:
+            self._unavailable(e)
+
+    def build_extension(self, ext):
+        try:
+            build_ext.build_extension(self, ext)
+        except (CCompilerError, DistutilsExecError) as e:
+            self._unavailable(e)
+
+    def _unavailable(self, e):
+        print('*' * 80)
+        print("""WARNING:
+
+        An optional code optimization (C extension) could not be compiled.
+
+        Optimizations for this package will not be available!""")
+        print()
+        print(e)
+        print('*' * 80)
+
+try:
     from setuptools import setup, Extension, Feature
 except ImportError:
     # do we need to support plain distutils for building when even
@@ -58,7 +94,7 @@
         zip_safe = False,
         tests_require = tests_require,
         install_requires = ['setuptools'],
-        extras_require={'docs': ['Sphinx'],
+        extras_require={'docs': ['Sphinx', 'repoze.sphinx.autointerface'],
                         'test': tests_require,
                         'testing': testing_extras,
                        },
@@ -74,17 +110,6 @@
         read('CHANGES.txt')
         )
 
-try: # Zope setuptools versions
-    from build_ext_3 import optional_build_ext
-    # This is Python 3. Setuptools is now required, and so is zope.fixers.
-    extra['install_requires'] = ['setuptools']
-    extra['setup_requires'] = ['zope.fixers']
-    extra['use_2to3'] = True
-    extra['use_2to3_fixers'] = ['zope.fixers']
-
-except (ImportError, SyntaxError):
-    from build_ext_2 import optional_build_ext
-    
 setup(name='zope.interface',
       version='4.0.0dev',
       url='http://pypi.python.org/pypi/zope.interface',

Copied: zope.interface/trunk/src/zope/interface/_compat.py (from rev 125011, zope.interface/branches/tseaver-no_2to3/src/zope/interface/_compat.py)
===================================================================
--- zope.interface/trunk/src/zope/interface/_compat.py	                        (rev 0)
+++ zope.interface/trunk/src/zope/interface/_compat.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -0,0 +1,69 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+"""Basic components support
+"""
+import sys
+import types
+
+if sys.version_info[0] < 3: #pragma NO COVER
+
+    def _u(s):
+        return unicode(s, 'unicode_escape')
+
+    def _normalize_name(name):
+        if isinstance(name, basestring):
+            return unicode(name)
+        raise TypeError("name must be a regular or unicode string")
+
+    CLASS_TYPES = (type, types.ClassType)
+    STRING_TYPES = (basestring,)
+
+    _BUILTINS = '__builtin__'
+
+    PYTHON3 = False
+    PYTHON2 = True
+
+else: #pragma NO COVER
+
+    def _u(s):
+        return s
+
+    def _normalize_name(name):
+        if isinstance(name, bytes):
+            name = str(name, 'ascii')
+        if isinstance(name, str):
+            return name
+        raise TypeError("name must be a string or ASCII-only bytes")
+
+    CLASS_TYPES = (type,)
+    STRING_TYPES = (str,)
+
+    _BUILTINS = 'builtins'
+
+    PYTHON3 = True
+    PYTHON2 = False
+
+def _skip_under_py3k(test_method): #pragma NO COVER
+    if sys.version_info[0] < 3:
+        return test_method
+    def _dummy(*args):
+        pass
+    return _dummy
+
+def _skip_under_py2(test_method): #pragma NO COVER
+    if sys.version_info[0] > 2:
+        return test_method
+    def _dummy(*args):
+        pass
+    return _dummy

Modified: zope.interface/trunk/src/zope/interface/adapter.py
===================================================================
--- zope.interface/trunk/src/zope/interface/adapter.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/adapter.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -18,7 +18,11 @@
 from zope.interface import providedBy
 from zope.interface import Interface
 from zope.interface import ro
+from zope.interface._compat import _u
+from zope.interface._compat import _normalize_name
 
+_BLANK = _u('')
+
 class BaseAdapterRegistry(object):
 
     # List of methods copied from lookup sub-objects:
@@ -128,7 +132,7 @@
 
         self.changed(self)
 
-    def registered(self, required, provided, name=u''):
+    def registered(self, required, provided, name=_BLANK):
         required = tuple(map(_convert_None_to_Interface, required))
         name = _normalize_name(name)
         order = len(required)
@@ -199,7 +203,7 @@
 
     def subscribe(self, required, provided, value):
         required = tuple(map(_convert_None_to_Interface, required))
-        name = u''
+        name = _BLANK
         order = len(required)
         byorder = self._subscribers
         while len(byorder) <= order:
@@ -244,7 +248,7 @@
             lookups.append((components, k))
             components = d
 
-        old = components.get(u'')
+        old = components.get(_BLANK)
         if not old:
             # this is belt-and-suspenders against the failure of cleanup below
             return  #pragma NO COVERAGE 
@@ -258,16 +262,16 @@
             return
 
         if new:
-            components[u''] = new
+            components[_BLANK] = new
         else:
-            # Instead of setting components[u''] = new, we clean out
+            # Instead of setting components[_BLANK] = new, we clean out
             # empty containers, since we don't want our keys to
             # reference global objects (interfaces) unnecessarily.  This
             # is often a problem when an interface is slated for
             # removal; a hold-over entry in the registry can make it
             # difficult to remove such interfaces.
-            if u'' in components:
-                del components[u'']
+            if _BLANK in components:
+                del components[_BLANK]
             for comp, k in reversed(lookups):
                 d = comp[k]
                 if d:
@@ -319,8 +323,9 @@
             cache = c
         return cache
 
-    def lookup(self, required, provided, name=u'', default=None):
+    def lookup(self, required, provided, name=_BLANK, default=None):
         cache = self._getcache(provided, name)
+        required = tuple(required)
         if len(required) == 1:
             result = cache.get(required[0], _not_in_mapping)
         else:
@@ -338,7 +343,7 @@
 
         return result
 
-    def lookup1(self, required, provided, name=u'', default=None):
+    def lookup1(self, required, provided, name=_BLANK, default=None):
         cache = self._getcache(provided, name)
         result = cache.get(required, _not_in_mapping)
         if result is _not_in_mapping:
@@ -349,10 +354,10 @@
 
         return result
 
-    def queryAdapter(self, object, provided, name=u'', default=None):
+    def queryAdapter(self, object, provided, name=_BLANK, default=None):
         return self.adapter_hook(provided, object, name, default)
 
-    def adapter_hook(self, provided, object, name=u'', default=None):
+    def adapter_hook(self, provided, object, name=_BLANK, default=None):
         required = providedBy(object)
         cache = self._getcache(provided, name)
         factory = cache.get(required, _not_in_mapping)
@@ -510,7 +515,8 @@
                 r.subscribe(self)
                 _refs[ref] = 1
 
-    def _uncached_lookup(self, required, provided, name=u''):
+    def _uncached_lookup(self, required, provided, name=_BLANK):
+        required = tuple(required)
         result = None
         order = len(required)
         for registry in self._registry.ro:
@@ -532,7 +538,7 @@
 
         return result
 
-    def queryMultiAdapter(self, objects, provided, name=u'', default=None):
+    def queryMultiAdapter(self, objects, provided, name=_BLANK, default=None):
         factory = self.lookup(map(providedBy, objects), provided, name)
         if factory is None:
             return default
@@ -544,6 +550,7 @@
         return result
 
     def _uncached_lookupAll(self, required, provided):
+        required = tuple(required)
         order = len(required)
         result = {}
         for registry in reversed(self._registry.ro):
@@ -558,12 +565,13 @@
 
         self._subscribe(*required)
 
-        return tuple(result.iteritems())
+        return tuple(result.items())
 
     def names(self, required, provided):
         return [c[0] for c in self.lookupAll(required, provided)]
 
     def _uncached_subscriptions(self, required, provided):
+        required = tuple(required)
         order = len(required)
         result = []
         for registry in reversed(self._registry.ro):
@@ -578,7 +586,7 @@
                 if extendors is None:
                     continue
 
-            _subscriptions(byorder[order], required, extendors, u'',
+            _subscriptions(byorder[order], required, extendors, _BLANK,
                            result, 0, order)
 
         self._subscribe(*required)
@@ -651,12 +659,6 @@
     else:
         return x
 
-def _normalize_name(name):
-    if isinstance(name, basestring):
-        return unicode(name)
-
-    raise TypeError("name must be a regular or unicode string")
-
 def _lookup(components, specs, provided, name, i, l):
     if i < l:
         for spec in specs[i].__sro__:

Modified: zope.interface/trunk/src/zope/interface/advice.py
===================================================================
--- zope.interface/trunk/src/zope/interface/advice.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/advice.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -28,9 +28,10 @@
 from types import FunctionType
 try:
     from types import ClassType
+except ImportError:  #pragma NO COVER Python > 3.x
+    __python3 = True
+else: #pragma NO COVER Python < 3.x
     __python3 = False
-except ImportError:  #pragma NO COVER
-    __python3 = True
     
 import sys
 
@@ -93,6 +94,10 @@
     callbacks *after* the last '__metaclass__' assignment in the containing
     class will be executed.  Be sure that classes using "advising" functions
     declare any '__metaclass__' *first*, to ensure all callbacks are run."""
+    # This entire approach is invalid under Py3K.  Don't even try to fix
+    # the coverage for this block there. :(
+    if __python3: #pragma NO COVER
+        raise TypeError('Class advice impossible in Python3')
 
     frame = sys._getframe(depth)
     kind, module, caller_locals, caller_globals = getFrameInfo(frame)
@@ -183,7 +188,7 @@
 def minimalBases(classes):
     """Reduce a list of base classes to its ordered minimum equivalent"""
 
-    if not __python3:
+    if not __python3: #pragma NO COVER
         classes = [c for c in classes if c is not ClassType]
     candidates = []
 

Modified: zope.interface/trunk/src/zope/interface/declarations.py
===================================================================
--- zope.interface/trunk/src/zope/interface/declarations.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/declarations.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -30,16 +30,25 @@
 from types import FunctionType
 from types import MethodType
 from types import ModuleType
+import warnings
 import weakref
 
 from zope.interface.advice import addClassAdvisor
 from zope.interface.interface import InterfaceClass
 from zope.interface.interface import SpecificationBase
 from zope.interface.interface import Specification
+from zope.interface._compat import CLASS_TYPES as DescriptorAwareMetaClasses
+from zope.interface._compat import PYTHON3
 
 # Registry of class-implementation specifications
 BuiltinImplementationSpecifications = {}
 
+_ADVICE_ERROR = ('Class advice impossible in Python3.  '
+                 'Use the @%s class decorator instead.')
+
+_ADVICE_WARNING = ('The %s API is deprecated, and will not work in Python3  '
+                   'Use the @%s class decorator instead.')
+
 class Declaration(Specification):
     """Interface declarations"""
 
@@ -55,116 +64,23 @@
 
     def __contains__(self, interface):
         """Test whether an interface is in the specification
-
-        for example:
-
-          >>> from zope.interface import Interface
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Declaration(I2, I3)
-          >>> spec = Declaration(I4, spec)
-          >>> int(I1 in spec)
-          0
-          >>> int(I2 in spec)
-          1
-          >>> int(I3 in spec)
-          1
-          >>> int(I4 in spec)
-          1
         """
+
         return self.extends(interface) and interface in self.interfaces()
 
     def __iter__(self):
         """Return an iterator for the interfaces in the specification
-
-        for example:
-
-          >>> from zope.interface import Interface
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Declaration(I2, I3)
-          >>> spec = Declaration(I4, spec)
-          >>> i = iter(spec)
-          >>> [x.getName() for x in i]
-          ['I4', 'I2', 'I3']
-          >>> list(i)
-          []
         """
         return self.interfaces()
 
     def flattened(self):
         """Return an iterator of all included and extended interfaces
-
-        for example:
-
-          >>> from zope.interface import Interface
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Declaration(I2, I3)
-          >>> spec = Declaration(I4, spec)
-          >>> i = spec.flattened()
-          >>> [x.getName() for x in i]
-          ['I4', 'I2', 'I1', 'I3', 'Interface']
-          >>> list(i)
-          []
-
         """
         return iter(self.__iro__)
 
     def __sub__(self, other):
         """Remove interfaces from a specification
-
-        Examples:
-
-          >>> from zope.interface import Interface
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Declaration()
-          >>> [iface.getName() for iface in spec]
-          []
-          >>> spec -= I1
-          >>> [iface.getName() for iface in spec]
-          []
-          >>> spec -= Declaration(I1, I2)
-          >>> [iface.getName() for iface in spec]
-          []
-          >>> spec = Declaration(I2, I4)
-          >>> [iface.getName() for iface in spec]
-          ['I2', 'I4']
-          >>> [iface.getName() for iface in spec - I4]
-          ['I2']
-          >>> [iface.getName() for iface in spec - I1]
-          ['I4']
-          >>> [iface.getName() for iface
-          ...  in spec - Declaration(I3, I4)]
-          ['I2']
-
         """
-
         return Declaration(
             *[i for i in self.interfaces()
                 if not [j for j in other.interfaces()
@@ -174,41 +90,7 @@
 
     def __add__(self, other):
         """Add two specifications or a specification and an interface
-
-        Examples:
-
-          >>> from zope.interface import Interface
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Declaration()
-          >>> [iface.getName() for iface in spec]
-          []
-          >>> [iface.getName() for iface in spec+I1]
-          ['I1']
-          >>> [iface.getName() for iface in I1+spec]
-          ['I1']
-          >>> spec2 = spec
-          >>> spec += I1
-          >>> [iface.getName() for iface in spec]
-          ['I1']
-          >>> [iface.getName() for iface in spec2]
-          []
-          >>> spec2 += Declaration(I3, I4)
-          >>> [iface.getName() for iface in spec2]
-          ['I3', 'I4']
-          >>> [iface.getName() for iface in spec+spec2]
-          ['I1', 'I3', 'I4']
-          >>> [iface.getName() for iface in spec2+spec]
-          ['I3', 'I4', 'I1']
-
         """
-
         seen = {}
         result = []
         for i in self.interfaces():
@@ -251,40 +133,7 @@
     """Return the interfaces implemented for a class' instances
 
       The value returned is an IDeclaration.
-
-      for example:
-
-        >>> from zope.interface import Interface
-        >>> class I1(Interface): pass
-        ...
-        >>> class I2(I1): pass
-        ...
-        >>> class I3(Interface): pass
-        ...
-        >>> class I4(I3): pass
-        ...
-        >>> class C1(object):
-        ...   implements(I2)
-        >>> class C2(C1):
-        ...   implements(I3)
-        >>> [i.getName() for i in implementedBy(C2)]
-        ['I3', 'I2']
-
-      Really, any object should be able to receive a successful answer, even
-      an instance:
-
-        >>> class Callable(object):
-        ...     def __call__(self):
-        ...         return self
-
-        >>> implementedBy(Callable())
-        <implementedBy zope.interface.declarations.?>
-
-      Note that the name of the spec ends with a '?', because the `Callable`
-      instance does not have a `__name__` attribute.
-      """
-    # This also manages storage of implementation specifications
-
+    """
     try:
         spec = cls.__dict__.get('__implemented__')
     except AttributeError:
@@ -377,31 +226,7 @@
 
       The interfaces given (including the interfaces in the specifications)
       replace any previous declarations.
-
-      Consider the following example:
-
-        >>> from zope.interface import Interface
-        >>> class I1(Interface): pass
-        ...
-        >>> class I2(Interface): pass
-        ...
-        >>> class I3(Interface): pass
-        ...
-        >>> class I4(Interface): pass
-        ...
-        >>> class A(object):
-        ...   implements(I3)
-        >>> class B(object):
-        ...   implements(I4)
-        >>> class C(A, B):
-        ...   pass
-        >>> classImplementsOnly(C, I1, I2)
-        >>> [i.getName() for i in implementedBy(C)]
-        ['I1', 'I2']
-
-      Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
-      whatever interfaces instances of ``A`` and ``B`` implement.
-      """
+    """
     spec = implementedBy(cls)
     spec.declared = ()
     spec.inherit = None
@@ -415,37 +240,7 @@
 
       The interfaces given (including the interfaces in the specifications)
       are added to any interfaces previously declared.
-
-      Consider the following example:
-
-        >>> from zope.interface import Interface
-        >>> class I1(Interface): pass
-        ...
-        >>> class I2(Interface): pass
-        ...
-        >>> class I3(Interface): pass
-        ...
-        >>> class I4(Interface): pass
-        ...
-        >>> class I5(Interface): pass
-        ...
-        >>> class A(object):
-        ...   implements(I3)
-        >>> class B(object):
-        ...   implements(I4)
-        >>> class C(A, B):
-        ...   pass
-        >>> classImplements(C, I1, I2)
-        >>> [i.getName() for i in implementedBy(C)]
-        ['I1', 'I2', 'I3', 'I4']
-        >>> classImplements(C, I5)
-        >>> [i.getName() for i in implementedBy(C)]
-        ['I1', 'I2', 'I5', 'I3', 'I4']
-
-      Instances of ``C`` provide ``I1``, ``I2``, ``I5``, and whatever
-      interfaces instances of ``A`` and ``B`` provide.
-      """
-
+    """
     spec = implementedBy(cls)
     spec.declared += tuple(_normalizeargs(interfaces))
 
@@ -463,7 +258,7 @@
             b = implementedBy(c)
             if b not in seen:
                 seen[b] = 1
-                bases.append(b)            
+                bases.append(b)
 
     spec.__bases__ = tuple(bases)
 
@@ -475,15 +270,42 @@
 
 
 class implementer:
+    """Declare the interfaces implemented by instances of a class.
 
+      This function is called as a class decorator.
+
+      The arguments are one or more interfaces or interface
+      specifications (IDeclaration objects).
+
+      The interfaces given (including the interfaces in the
+      specifications) are added to any interfaces previously
+      declared.
+
+      Previous declarations include declarations for base classes
+      unless implementsOnly was used.
+
+      This function is provided for convenience. It provides a more
+      convenient way to call classImplements. For example::
+
+        @implementer(I1)
+        class C(object):
+            pass
+
+      is equivalent to calling::
+
+        classImplements(C, I1)
+
+      after the class has been created.
+      """
+
     def __init__(self, *interfaces):
         self.interfaces = interfaces
 
     def __call__(self, ob):
         if isinstance(ob, DescriptorAwareMetaClasses):
             classImplements(ob, *self.interfaces)
-            return ob            
-        
+            return ob
+
         spec = Implements(*self.interfaces)
         try:
             ob.__implemented__ = spec
@@ -492,7 +314,29 @@
         return ob
 
 class implementer_only:
+    """Declare the only interfaces implemented by instances of a class
 
+      This function is called as a class decorator.
+
+      The arguments are one or more interfaces or interface
+      specifications (IDeclaration objects).
+
+      Previous declarations including declarations for base classes
+      are overridden.
+
+      This function is provided for convenience. It provides a more
+      convenient way to call classImplementsOnly. For example::
+
+        @implementer_only(I1)
+        class C(object): pass
+
+      is equivalent to calling::
+
+        classImplementsOnly(I1)
+
+      after the class has been created.
+      """
+
     def __init__(self, *interfaces):
         self.interfaces = interfaces
 
@@ -506,17 +350,20 @@
         else:
             # Assume it's a class:
             classImplementsOnly(ob, *self.interfaces)
-            return ob            
-        
+            return ob
+
 def _implements(name, interfaces, classImplements):
+    # This entire approach is invalid under Py3K.  Don't even try to fix
+    # the coverage for this block there. :(
+    if PYTHON3: #pragma NO COVER
+        raise TypeError('Class advice impossible in Python3')
     frame = sys._getframe(2)
     locals = frame.f_locals
 
     # Try to make sure we were called from a class def. In 2.2.0 we can't
     # check for __module__ since it doesn't seem to be added to the locals
     # until later on.
-    if (locals is frame.f_globals) or (
-        ('__module__' not in locals) and sys.version_info[:3] > (2, 2, 0)):
+    if locals is frame.f_globals or '__module__' not in locals:
         raise TypeError(name+" can be used only from a class definition.")
 
     if '__implements_advice_data__' in locals:
@@ -550,41 +397,14 @@
         classImplements(C, I1)
 
       after the class has been created.
-
-      Consider the following example::
-
-
-        >>> from zope.interface import Interface
-        >>> class IA1(Interface): pass
-        ...
-        >>> class IA2(Interface): pass
-        ...
-        >>> class IB(Interface): pass
-        ...
-        >>> class IC(Interface): pass
-        ...
-        >>> class A(object):
-        ...     implements(IA1, IA2)
-        >>> class B(object):
-        ...     implements(IB)
-
-        >>> class C(A, B):
-        ...    implements(IC)
-
-        >>> ob = C()
-        >>> int(IA1 in providedBy(ob))
-        1
-        >>> int(IA2 in providedBy(ob))
-        1
-        >>> int(IB in providedBy(ob))
-        1
-        >>> int(IC in providedBy(ob))
-        1
-
-      Instances of ``C`` implement ``I1``, ``I2``, and whatever interfaces
-      instances of ``A`` and ``B`` implement.
-
-      """
+    """
+    # This entire approach is invalid under Py3K.  Don't even try to fix
+    # the coverage for this block there. :(
+    if PYTHON3: #pragma NO COVER
+        raise TypeError(_ADVICE_ERROR % 'implementer')
+    else:
+        warnings.warn(_ADVICE_WARNING % ('implements', 'implementer'),
+                      DeprecationWarning, 2)
     _implements("implements", interfaces, classImplements)
 
 def implementsOnly(*interfaces):
@@ -608,41 +428,14 @@
         classImplementsOnly(I1)
 
       after the class has been created.
-
-      Consider the following example::
-
-        >>> from zope.interface import Interface
-        >>> class IA1(Interface): pass
-        ...
-        >>> class IA2(Interface): pass
-        ...
-        >>> class IB(Interface): pass
-        ...
-        >>> class IC(Interface): pass
-        ...
-        >>> class A(object):
-        ...     implements(IA1, IA2)
-        >>> class B(object):
-        ...     implements(IB)
-
-        >>> class C(A, B):
-        ...    implementsOnly(IC)
-
-        >>> ob = C()
-        >>> int(IA1 in providedBy(ob))
-        0
-        >>> int(IA2 in providedBy(ob))
-        0
-        >>> int(IB in providedBy(ob))
-        0
-        >>> int(IC in providedBy(ob))
-        1
-
-
-      Instances of ``C`` implement ``IC``, regardless of what
-      instances of ``A`` and ``B`` implement.
-
-      """
+    """
+    # This entire approach is invalid under Py3K.  Don't even try to fix
+    # the coverage for this block there. :(
+    if PYTHON3: #pragma NO COVER
+        raise TypeError(_ADVICE_ERROR % 'implementer_only')
+    else:
+        warnings.warn(_ADVICE_WARNING % ('implementsOnly', 'implementer_only'),
+                      DeprecationWarning, 2)
     _implements("implementsOnly", interfaces, classImplementsOnly)
 
 ##############################################################################
@@ -667,22 +460,6 @@
 
     def __get__(self, inst, cls):
         """Make sure that a class __provides__ doesn't leak to an instance
-
-        For example:
-
-          >>> from zope.interface import Interface
-          >>> class IFooFactory(Interface): pass
-          ...
-
-          >>> class C(object):
-          ...   pass
-
-          >>> C.__provides__ = ProvidesClass(C, IFooFactory)
-          >>> [i.getName() for i in C.__provides__]
-          ['IFooFactory']
-          >>> getattr(C(), '__provides__', 0)
-          0
-
         """
         if inst is None and cls is self._cls:
             # We were accessed through a class, so we are the class'
@@ -703,70 +480,17 @@
 
       Instance declarations are shared among instances that have the same
       declaration. The declarations are cached in a weak value dictionary.
-
-      (Note that, in the examples below, we are going to make assertions about
-       the size of the weakvalue dictionary.  For the assertions to be
-       meaningful, we need to force garbage collection to make sure garbage
-       objects are, indeed, removed from the system. Depending on how Python
-       is run, we may need to make multiple calls to be sure.  We provide a
-       collect function to help with this:
-
-       >>> import gc
-       >>> def collect():
-       ...     for i in range(4):
-       ...         gc.collect()
-
-      )
-
-      >>> collect()
-      >>> before = len(InstanceDeclarations)
-
-      >>> class C(object):
-      ...    pass
-
-      >>> from zope.interface import Interface
-      >>> class I(Interface):
-      ...    pass
-
-      >>> c1 = C()
-      >>> c2 = C()
-
-      >>> len(InstanceDeclarations) == before
-      1
-
-      >>> directlyProvides(c1, I)
-      >>> len(InstanceDeclarations) == before + 1
-      1
-
-      >>> directlyProvides(c2, I)
-      >>> len(InstanceDeclarations) == before + 1
-      1
-
-      >>> del c1
-      >>> collect()
-      >>> len(InstanceDeclarations) == before + 1
-      1
-
-      >>> del c2
-      >>> collect()
-      >>> len(InstanceDeclarations) == before
-      1
-      """
-
+    """
     spec = InstanceDeclarations.get(interfaces)
     if spec is None:
         spec = ProvidesClass(*interfaces)
         InstanceDeclarations[interfaces] = spec
 
     return spec
+
 Provides.__safe_for_unpickling__ = True
 
-try:
-    from types import ClassType
-    DescriptorAwareMetaClasses = ClassType, type
-except ImportError:  #pragma NO COVERAGE  (Python 3)
-    DescriptorAwareMetaClasses = (type,)
-    
+
 def directlyProvides(object, *interfaces):
     """Declare interfaces declared directly for an object
 
@@ -775,82 +499,14 @@
 
       The interfaces given (including the interfaces in the specifications)
       replace interfaces previously declared for the object.
-
-      Consider the following example:
-
-        >>> from zope.interface import Interface
-        >>> class I1(Interface): pass
-        ...
-        >>> class I2(Interface): pass
-        ...
-        >>> class IA1(Interface): pass
-        ...
-        >>> class IA2(Interface): pass
-        ...
-        >>> class IB(Interface): pass
-        ...
-        >>> class IC(Interface): pass
-        ...
-        >>> class A(object):
-        ...     implements(IA1, IA2)
-        >>> class B(object):
-        ...     implements(IB)
-
-        >>> class C(A, B):
-        ...    implements(IC)
-
-        >>> ob = C()
-        >>> directlyProvides(ob, I1, I2)
-        >>> int(I1 in providedBy(ob))
-        1
-        >>> int(I2 in providedBy(ob))
-        1
-        >>> int(IA1 in providedBy(ob))
-        1
-        >>> int(IA2 in providedBy(ob))
-        1
-        >>> int(IB in providedBy(ob))
-        1
-        >>> int(IC in providedBy(ob))
-        1
-
-      The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
-      instances have been declared for instances of ``C``.
-
-      To remove directly provided interfaces, use ``directlyProvidedBy`` and
-      subtract the unwanted interfaces. For example:
-
-        >>> directlyProvides(ob, directlyProvidedBy(ob)-I2)
-        >>> int(I1 in providedBy(ob))
-        1
-        >>> int(I2 in providedBy(ob))
-        0
-
-      removes I2 from the interfaces directly provided by ``ob``. The object,
-      ``ob`` no longer directly provides ``I2``, although it might still
-      provide ``I2`` if it's class implements ``I2``.
-
-      To add directly provided interfaces, use ``directlyProvidedBy`` and
-      include additional interfaces.  For example:
-
-        >>> int(I2 in providedBy(ob))
-        0
-        >>> directlyProvides(ob, directlyProvidedBy(ob), I2)
-
-      adds ``I2`` to the interfaces directly provided by ob::
-
-        >>> int(I2 in providedBy(ob))
-        1
-
-      """
-
-    # We need to avoid setting this attribute on meta classes that
-    # don't support descriptors.
-    # We can do away with this check when we get rid of the old EC
+    """
     cls = getattr(object, '__class__', None)
     if cls is not None and getattr(cls,  '__class__', None) is cls:
         # It's a meta class (well, at least it it could be an extension class)
-        if not isinstance(object, DescriptorAwareMetaClasses):
+        # Note that we can't get here from Py3k tests:  there is no normal
+        # class which isn't descriptor aware.
+        if not isinstance(object,
+                          DescriptorAwareMetaClasses): #pragma NO COVER Py3k
             raise TypeError("Attempt to make an interface declaration on a "
                             "non-descriptor-aware class")
 
@@ -879,101 +535,13 @@
 
     The interfaces given (including the interfaces in the specifications) are
     added to the interfaces previously declared for the object.
-
-    Consider the following example:
-
-      >>> from zope.interface import Interface
-      >>> class I1(Interface): pass
-      ...
-      >>> class I2(Interface): pass
-      ...
-      >>> class IA1(Interface): pass
-      ...
-      >>> class IA2(Interface): pass
-      ...
-      >>> class IB(Interface): pass
-      ...
-      >>> class IC(Interface): pass
-      ...
-      >>> class A(object):
-      ...     implements(IA1, IA2)
-      >>> class B(object):
-      ...     implements(IB)
-
-      >>> class C(A, B):
-      ...    implements(IC)
-
-      >>> ob = C()
-      >>> directlyProvides(ob, I1)
-      >>> int(I1 in providedBy(ob))
-      1
-      >>> int(I2 in providedBy(ob))
-      0
-      >>> int(IA1 in providedBy(ob))
-      1
-      >>> int(IA2 in providedBy(ob))
-      1
-      >>> int(IB in providedBy(ob))
-      1
-      >>> int(IC in providedBy(ob))
-      1
-
-      >>> alsoProvides(ob, I2)
-      >>> int(I1 in providedBy(ob))
-      1
-      >>> int(I2 in providedBy(ob))
-      1
-      >>> int(IA1 in providedBy(ob))
-      1
-      >>> int(IA2 in providedBy(ob))
-      1
-      >>> int(IB in providedBy(ob))
-      1
-      >>> int(IC in providedBy(ob))
-      1
-
-    The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
-    instances have been declared for instances of ``C``. Notice that the
-    alsoProvides just extends the provided interfaces.
     """
     directlyProvides(object, directlyProvidedBy(object), *interfaces)
 
 def noLongerProvides(object, interface):
+    """ Removes a directly provided interface from an object.
     """
-    This removes a directly provided interface from an object.
-    Consider the following two interfaces:
-
-      >>> from zope.interface import Interface
-      >>> class I1(Interface): pass
-      ...
-      >>> class I2(Interface): pass
-      ...
-
-    ``I1`` is provided through the class, ``I2`` is directly provided
-    by the object:
-    
-      >>> class C(object):
-      ...    implements(I1)
-      >>> c = C()
-      >>> alsoProvides(c, I2)
-      >>> I2.providedBy(c)
-      True
-
-    Remove I2 from c again:
-      
-      >>> noLongerProvides(c, I2)
-      >>> I2.providedBy(c)
-      False
-
-    Removing an interface that is provided through the class is not possible:
-
-      >>> noLongerProvides(c, I1)
-      Traceback (most recent call last):
-      ...
-      ValueError: Can only remove directly provided interfaces.
-
-    """
-    directlyProvides(object, directlyProvidedBy(object)-interface)
+    directlyProvides(object, directlyProvidedBy(object) - interface)
     if interface.providedBy(object):
         raise ValueError("Can only remove directly provided interfaces.")
 
@@ -1010,24 +578,7 @@
     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):
-      ...     implements(IFoo)
-      ...     classProvides(IFooFactory)
-      >>> [i.getName() for i in C.__provides__]
-      ['IFooFactory']
-
-      >>> [i.getName() for i in C().__provides__]
-      ['IFoo']
     """
-
     def __init__(self, cls, metacls, *interfaces):
         self._cls = cls
         self._implements = implementedBy(cls)
@@ -1085,44 +636,23 @@
         directlyProvides(theclass, I1)
 
       after the class has been created.
+    """
+    # This entire approach is invalid under Py3K.  Don't even try to fix
+    # the coverage for this block there. :(
+                       
+    if PYTHON3: #pragma NO COVER
+        raise TypeError(_ADVICE_ERROR % 'provider')
+    else:
+        warnings.warn(_ADVICE_WARNING % ('classProvides', 'provider'),
+                      DeprecationWarning, 2)
 
-      For example:
-
-        >>> from zope.interface import Interface
-        >>> class IFoo(Interface): pass
-        ...
-        >>> class IFooFactory(Interface): pass
-        ...
-        >>> class C(object):
-        ...   implements(IFoo)
-        ...   classProvides(IFooFactory)
-        >>> [i.getName() for i in C.__providedBy__]
-        ['IFooFactory']
-        >>> [i.getName() for i in C().__providedBy__]
-        ['IFoo']
-
-      if equivalent to:
-
-        >>> from zope.interface import Interface
-        >>> class IFoo(Interface): pass
-        ...
-        >>> class IFooFactory(Interface): pass
-        ...
-        >>> class C(object):
-        ...   implements(IFoo)
-        >>> directlyProvides(C, IFooFactory)
-        >>> [i.getName() for i in C.__providedBy__]
-        ['IFooFactory']
-        >>> [i.getName() for i in C().__providedBy__]
-        ['IFoo']
-
-      """
     frame = sys._getframe(1)
     locals = frame.f_locals
 
     # Try to make sure we were called from a class def
     if (locals is frame.f_globals) or ('__module__' not in locals):
-        raise TypeError("classProvides can be used only from a class definition.")
+        raise TypeError("classProvides can be used only from a "
+                        "class definition.")
 
     if '__provides__' in locals:
         raise TypeError(
@@ -1133,6 +663,8 @@
     addClassAdvisor(_classProvides_advice, depth=2)
 
 def _classProvides_advice(cls):
+    # This entire approach is invalid under Py3K.  Don't even try to fix
+    # the coverage for this block there. :(
     interfaces = cls.__dict__['__provides__']
     del cls.__provides__
     directlyProvides(cls, *interfaces)
@@ -1146,7 +678,7 @@
 
     def __call__(self, ob):
         directlyProvides(ob, *self.interfaces)
-        return ob            
+        return ob
 
 def moduleProvides(*interfaces):
     """Declare interfaces provided by a module
@@ -1196,68 +728,7 @@
     """Provide object specifications
 
     These combine information for the object and for it's classes.
-
-    For example:
-
-      >>> from zope.interface import Interface
-      >>> 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 A(object):
-      ...     implements(I1)
-      >>> class B(object): __implemented__ = I2
-      ...
-      >>> class C(A, B):
-      ...     implements(I31)
-      >>> c = C()
-      >>> directlyProvides(c, I4)
-      >>> [i.getName() for i in providedBy(c)]
-      ['I4', 'I31', 'I1', 'I2']
-      >>> [i.getName() for i in providedBy(c).flattened()]
-      ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
-      >>> int(I1 in providedBy(c))
-      1
-      >>> int(I3 in providedBy(c))
-      0
-      >>> int(providedBy(c).extends(I3))
-      1
-      >>> int(providedBy(c).extends(I31))
-      1
-      >>> int(providedBy(c).extends(I5))
-      0
-      >>> class COnly(A, B):
-      ...     implementsOnly(I31)
-      >>> class D(COnly):
-      ...     implements(I5)
-      >>> c = D()
-      >>> directlyProvides(c, I4)
-      >>> [i.getName() for i in providedBy(c)]
-      ['I4', 'I5', 'I31']
-      >>> [i.getName() for i in providedBy(c).flattened()]
-      ['I4', 'I5', 'I31', 'I3', 'Interface']
-      >>> int(I1 in providedBy(c))
-      0
-      >>> int(I3 in providedBy(c))
-      0
-      >>> int(providedBy(c).extends(I3))
-      1
-      >>> int(providedBy(c).extends(I1))
-      0
-      >>> int(providedBy(c).extends(I31))
-      1
-      >>> int(providedBy(c).extends(I5))
-      1
     """
-
     return Provides(cls, direct) #pragma NO COVER fossil
 
 def getObjectSpecificationFallback(ob):
@@ -1337,27 +808,7 @@
 
     def __get__(self, inst, cls):
         """Get an object specification for an object
-
-        For example:
-
-          >>> from zope.interface import Interface
-          >>> class IFoo(Interface): pass
-          ...
-          >>> class IFooFactory(Interface): pass
-          ...
-          >>> class C(object):
-          ...   implements(IFoo)
-          ...   classProvides(IFooFactory)
-          >>> [i.getName() for i in C.__providedBy__]
-          ['IFooFactory']
-          >>> [i.getName() for i in C().__providedBy__]
-          ['IFoo']
-
         """
-
-        # Get an ObjectSpecification bound to either an instance or a class,
-        # depending on how we were accessed.
-
         if inst is None:
             return getObjectSpecification(cls)
 
@@ -1397,7 +848,7 @@
     import _zope_interface_coptimizations
 except ImportError: #pragma NO COVER
     pass
-else:
+else: #pragma NO COVER PyPy
     from _zope_interface_coptimizations import implementedBy
     from _zope_interface_coptimizations import providedBy
     from _zope_interface_coptimizations import getObjectSpecification

Modified: zope.interface/trunk/src/zope/interface/document.py
===================================================================
--- zope.interface/trunk/src/zope/interface/document.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/document.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -41,8 +41,7 @@
             outp(_justify_and_indent(_trim_doc_string(item), level, munge))
         level -= 1
 
-    namesAndDescriptions = I.namesAndDescriptions()
-    namesAndDescriptions.sort()
+    namesAndDescriptions = sorted(I.namesAndDescriptions())
 
     outp(_justify_and_indent("Attributes:", level, munge))
     level += 1

Modified: zope.interface/trunk/src/zope/interface/interface.py
===================================================================
--- zope.interface/trunk/src/zope/interface/interface.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/interface.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -16,6 +16,7 @@
 from __future__ import generators
 
 import sys
+from types import MethodType
 from types import FunctionType
 import warnings
 import weakref
@@ -92,69 +93,20 @@
 
     def providedBy(self, ob):
         """Is the interface implemented by an object
-
-          >>> from zope.interface import *
-          >>> class I1(Interface):
-          ...     pass
-          >>> class C(object):
-          ...     implements(I1)
-          >>> c = C()
-          >>> class X(object):
-          ...     pass
-          >>> x = X()
-          >>> I1.providedBy(x)
-          False
-          >>> I1.providedBy(C)
-          False
-          >>> I1.providedBy(c)
-          True
-          >>> directlyProvides(x, I1)
-          >>> I1.providedBy(x)
-          True
-          >>> directlyProvides(C, I1)
-          >>> I1.providedBy(C)
-          True
-
         """
         spec = providedBy(ob)
         return self in spec._implied
 
     def implementedBy(self, cls):
         """Test whether the specification is implemented by a class or factory.
-        Raise TypeError if argument is neither a class nor a callable."""
+
+        Raise TypeError if argument is neither a class nor a callable.
+        """
         spec = implementedBy(cls)
         return self in spec._implied
 
     def isOrExtends(self, interface):
         """Is the interface the same as or extend the given interface
-
-        Examples::
-
-          >>> from zope.interface import Interface
-          >>> from zope.interface.declarations import Declaration
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Declaration()
-          >>> int(spec.extends(Interface))
-          1
-          >>> spec = Declaration(I2)
-          >>> int(spec.extends(Interface))
-          1
-          >>> int(spec.extends(I1))
-          1
-          >>> int(spec.extends(I2))
-          1
-          >>> int(spec.extends(I3))
-          0
-          >>> int(spec.extends(I4))
-          0
-
         """
         return interface in self._implied
 
@@ -226,34 +178,6 @@
 
     Specifications are mutable.  If you reassign their bases, their
     relations with other specifications are adjusted accordingly.
-
-    For example:
-
-    >>> from zope.interface import Interface
-    >>> class I1(Interface):
-    ...     pass
-    >>> class I2(I1):
-    ...     pass
-    >>> class I3(I2):
-    ...     pass
-
-    >>> [i.__name__ for i in I1.__bases__]
-    ['Interface']
-
-    >>> [i.__name__ for i in I2.__bases__]
-    ['I1']
-
-    >>> I3.extends(I1)
-    1
-
-    >>> I2.__bases__ = (Interface, )
-
-    >>> [i.__name__ for i in I2.__bases__]
-    ['Interface']
-
-    >>> I3.extends(I1)
-    0
-
     """
 
     # Copy some base class methods for speed
@@ -329,26 +253,7 @@
 
 
     def interfaces(self):
-        """Return an iterator for the interfaces in the specification
-
-        for example::
-
-          >>> from zope.interface import Interface
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Specification((I2, I3))
-          >>> spec = Specification((I4, spec))
-          >>> i = spec.interfaces()
-          >>> [x.getName() for x in i]
-          ['I4', 'I2', 'I3']
-          >>> list(i)
-          []
+        """Return an iterator for the interfaces in the specification.
         """
         seen = {}
         for base in self.__bases__:
@@ -363,40 +268,6 @@
 
         Test whether an interface in the specification extends the
         given interface
-
-        Examples::
-
-          >>> from zope.interface import Interface
-          >>> from zope.interface.declarations import Declaration
-          >>> class I1(Interface): pass
-          ...
-          >>> class I2(I1): pass
-          ...
-          >>> class I3(Interface): pass
-          ...
-          >>> class I4(I3): pass
-          ...
-          >>> spec = Declaration()
-          >>> int(spec.extends(Interface))
-          1
-          >>> spec = Declaration(I2)
-          >>> int(spec.extends(Interface))
-          1
-          >>> int(spec.extends(I1))
-          1
-          >>> int(spec.extends(I2))
-          1
-          >>> int(spec.extends(I3))
-          0
-          >>> int(spec.extends(I4))
-          0
-          >>> I2.extends(I2)
-          0
-          >>> I2.extends(I2, False)
-          1
-          >>> I2.extends(I2, strict=False)
-          1
-
         """
         return ((interface in self._implied)
                 and
@@ -502,19 +373,7 @@
         self.__identifier__ = "%s.%s" % (self.__module__, self.__name__)
 
     def interfaces(self):
-        """Return an iterator for the interfaces in the specification
-
-        for example::
-
-          >>> from zope.interface import Interface
-          >>> class I1(Interface): pass
-          ...
-          >>>
-          >>> i = I1.interfaces()
-          >>> [x.getName() for x in i]
-          ['I1']
-          >>> list(i)
-          []
+        """Return an iterator for the interfaces in the specification.
         """
         yield self
 
@@ -577,7 +436,7 @@
         if hasattr(self, "_deferred"): return self._deferred
 
         klass={}
-        exec "class %s: pass" % self.__name__ in klass
+        exec("class %s: pass" % self.__name__, klass)
         klass=klass[self.__name__]
 
         self.__d(klass)
@@ -591,7 +450,7 @@
         for call in self.queryTaggedValue('invariants', []):
             try:
                 call(obj)
-            except Invalid, e:
+            except Invalid as e:
                 if errors is None:
                     raise
                 else:
@@ -777,12 +636,11 @@
 
         return "(%s)" % ", ".join(sig)
 
-
 def fromFunction(func, interface=None, imlevel=0, name=None):
     name = name or func.__name__
     method = Method(name, func.__doc__)
-    defaults = func.func_defaults or ()
-    code = func.func_code
+    defaults = getattr(func, '__defaults__', None) or ()
+    code = func.__code__
     # Number of positional arguments
     na = code.co_argcount-imlevel
     names = code.co_varnames[imlevel:]
@@ -824,7 +682,10 @@
 
 
 def fromMethod(meth, interface=None, name=None):
-    func = meth.im_func
+    if isinstance(meth, MethodType):
+        func = meth.__func__
+    else:
+        func = meth
     return fromFunction(func, interface, imlevel=1, name=name)
 
 

Modified: zope.interface/trunk/src/zope/interface/interfaces.py
===================================================================
--- zope.interface/trunk/src/zope/interface/interfaces.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/interfaces.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -17,9 +17,11 @@
 
 from zope.interface.interface import Attribute
 from zope.interface.interface import Interface
-from zope.interface.declarations import implements
-from zope.interface.declarations import implementer # required by py3k fixers
+from zope.interface.declarations import implementer
+from zope.interface._compat import _u
 
+_BLANK = _u('')
+
 class IElement(Interface):
     """Objects that have basic documentation and tagged values.
     """
@@ -84,6 +86,26 @@
 class ISpecification(Interface):
     """Object Behavioral specifications"""
 
+    def providedBy(object):
+        """Test whether the interface is implemented by the object
+
+        Return true of the object asserts that it implements the
+        interface, including asserting that it implements an extended
+        interface.
+        """
+
+    def implementedBy(class_):
+        """Test whether the interface is implemented by instances of the class
+
+        Return true of the class asserts that its instances implement the
+        interface, including asserting that they implement an extended
+        interface.
+        """
+
+    def isOrExtends(other):
+        """Test whether the specification is or extends another
+        """
+
     def extends(other, strict=True):
         """Test whether a specification extends another
 
@@ -93,10 +115,6 @@
         If strict is false, then the specification extends itself.
         """
 
-    def isOrExtends(other):
-        """Test whether the specification is or extends another
-        """
-
     def weakref(callback=None):
         """Return a weakref to the specification
 
@@ -227,22 +245,6 @@
 
     """
 
-    def providedBy(object):
-        """Test whether the interface is implemented by the object
-
-        Return true of the object asserts that it implements the
-        interface, including asserting that it implements an extended
-        interface.
-        """
-
-    def implementedBy(class_):
-        """Test whether the interface is implemented by instances of the class
-
-        Return true of the class asserts that its instances implement the
-        interface, including asserting that they implement an extended
-        interface.
-        """
-
     def names(all=False):
         """Get the interface attribute names
 
@@ -526,7 +528,7 @@
     def implements(*interfaces):
         """Declare interfaces implemented by instances of a class
 
-        This function is called in a class definition.
+        This function is called in a class definition (Python 2.x only).
 
         The arguments are one or more interfaces or interface
         specifications (IDeclaration objects).
@@ -549,7 +551,7 @@
 
         after the class has been created.
 
-        Consider the following example::
+        Consider the following example (Python 2.x only)::
 
           class C(A, B):
             implements(I1, I2)
@@ -562,7 +564,7 @@
     def implementsOnly(*interfaces):
         """Declare the only interfaces implemented by instances of a class
 
-        This function is called in a class definition.
+        This function is called in a class definition (Python 2.x only).
 
         The arguments are one or more interfaces or interface
         specifications (IDeclaration objects).
@@ -581,7 +583,7 @@
 
         after the class has been created.
 
-        Consider the following example::
+        Consider the following example (Python 2.x only)::
 
           class C(A, B):
             implementsOnly(I1, I2)
@@ -677,7 +679,7 @@
         provided interface, and a name.
         """
 
-    def registered(required, provided, name=u''):
+    def registered(required, provided, name=_BLANK):
         """Return the component registered for the given interfaces and name
 
         Unlike the lookup method, this methods won't retrieve
@@ -696,22 +698,22 @@
         specifications, a provided interface, and a name.
         """
 
-    def queryMultiAdapter(objects, provided, name=u'', default=None):
+    def queryMultiAdapter(objects, provided, name=_BLANK, default=None):
         """Adapt a sequence of objects to a named, provided, interface
         """
 
-    def lookup1(required, provided, name=u'', default=None):
+    def lookup1(required, provided, name=_BLANK, default=None):
         """Lookup a value using a single required interface
 
         A value is looked up based on a single required
         specifications, a provided interface, and a name.
         """
 
-    def queryAdapter(object, provided, name=u'', default=None):
+    def queryAdapter(object, provided, name=_BLANK, default=None):
         """Adapt an object using a registered adapter factory.
         """
 
-    def adapter_hook(provided, object, name=u'', default=None):
+    def adapter_hook(provided, object, name=_BLANK, default=None):
         """Adapt an object using a registered adapter factory.
         """
 
@@ -725,7 +727,7 @@
         """Return the names for which there are registered objects
         """
 
-    def subscribe(required, provided, subscriber, name=u''):
+    def subscribe(required, provided, subscriber, name=_BLANK):
         """Register a subscriber
 
         A subscriber is registered for a *sequence* of required
@@ -735,14 +737,14 @@
         equivalent) interfaces.
         """
 
-    def subscriptions(required, provided, name=u''):
+    def subscriptions(required, provided, name=_BLANK):
         """Get a sequence of subscribers
 
         Subscribers for a *sequence* of required interfaces, and a provided
         interface are returned.
         """
 
-    def subscribers(objects, provided, name=u''):
+    def subscribers(objects, provided, name=_BLANK):
         """Get a sequence of subscription adapters
         """
 
@@ -764,8 +766,8 @@
     object = Attribute("The subject of the event.")
 
 
+ at implementer(IObjectEvent)
 class ObjectEvent(object):
-    implements(IObjectEvent)
 
     def __init__(self, object):
         self.object = object
@@ -783,26 +785,26 @@
     utilities = Attribute(
         "Adapter Registry to manage all registered utilities.")
 
-    def queryAdapter(object, interface, name=u'', default=None):
+    def queryAdapter(object, interface, name=_BLANK, default=None):
         """Look for a named adapter to an interface for an object
 
         If a matching adapter cannot be found, returns the default.
         """
 
-    def getAdapter(object, interface, name=u''):
+    def getAdapter(object, interface, name=_BLANK):
         """Look for a named adapter to an interface for an object
 
         If a matching adapter cannot be found, a ComponentLookupError
         is raised.
         """
 
-    def queryMultiAdapter(objects, interface, name=u'', default=None):
+    def queryMultiAdapter(objects, interface, name=_BLANK, default=None):
         """Look for a multi-adapter to an interface for multiple objects
 
         If a matching adapter cannot be found, returns the default.
         """
 
-    def getMultiAdapter(objects, interface, name=u''):
+    def getMultiAdapter(objects, interface, name=_BLANK):
         """Look for a multi-adapter to an interface for multiple objects
 
         If a matching adapter cannot be found, a ComponentLookupError
@@ -914,11 +916,11 @@
 class IRegistrationEvent(IObjectEvent):
     """An event that involves a registration"""
 
+
+ at implementer(IRegistrationEvent)
 class RegistrationEvent(ObjectEvent):
     """There has been a change in a registration
     """
-    implements(IRegistrationEvent)
-
     def __repr__(self):
         return "%s event:\n%r" % (self.__class__.__name__, self.object)
 
@@ -926,24 +928,26 @@
     """A component or factory was registered
     """
 
+ at implementer(IRegistered)
 class Registered(RegistrationEvent):
-    implements(IRegistered)
+    pass
 
 class IUnregistered(IRegistrationEvent):
     """A component or factory was unregistered
     """
 
+ at implementer(IUnregistered)
 class Unregistered(RegistrationEvent):
     """A component or factory was unregistered
     """
-    implements(IUnregistered)
+    pass
 
 class IComponentRegistry(Interface):
     """Register components
     """
 
-    def registerUtility(component=None, provided=None, name=u'',
-                        info=u'', factory=None):
+    def registerUtility(component=None, provided=None, name=_BLANK,
+                        info=_BLANK, factory=None):
         """Register a utility
 
         factory
@@ -969,7 +973,7 @@
         A Registered event is generated with an IUtilityRegistration.
         """
 
-    def unregisterUtility(component=None, provided=None, name=u'',
+    def unregisterUtility(component=None, provided=None, name=_BLANK,
                           factory=None):
         """Unregister a utility
 
@@ -1008,8 +1012,8 @@
         in the object.
         """
 
-    def registerAdapter(factory, required=None, provided=None, name=u'',
-                       info=u''):
+    def registerAdapter(factory, required=None, provided=None, name=_BLANK,
+                       info=_BLANK):
         """Register an adapter factory
 
         Parameters:
@@ -1046,7 +1050,7 @@
         """
 
     def unregisterAdapter(factory=None, required=None,
-                          provided=None, name=u''):
+                          provided=None, name=_BLANK):
         """Register an adapter factory
 
         A boolean is returned indicating whether the registry was
@@ -1096,7 +1100,7 @@
         """
 
     def registerSubscriptionAdapter(factory, required=None, provides=None,
-                                    name=u'', info=''):
+                                    name=_BLANK, info=''):
         """Register a subscriber factory
 
         Parameters:
@@ -1137,7 +1141,7 @@
         """
 
     def unregisterSubscriptionAdapter(factory=None, required=None,
-                                      provides=None, name=u''):
+                                      provides=None, name=_BLANK):
         """Unregister a subscriber factory.
 
         A boolean is returned indicating whether the registry was
@@ -1191,7 +1195,7 @@
         registrations in the object.
         """
 
-    def registerHandler(handler, required=None, name=u'', info=''):
+    def registerHandler(handler, required=None, name=_BLANK, info=''):
         """Register a handler.
 
         A handler is a subscriber that doesn't compute an adapter
@@ -1229,7 +1233,7 @@
         A Registered event is generated with an IHandlerRegistration.
         """
 
-    def unregisterHandler(handler=None, required=None, name=u''):
+    def unregisterHandler(handler=None, required=None, name=_BLANK):
         """Unregister a handler.
 
         A handler is a subscriber that doesn't compute an adapter

Modified: zope.interface/trunk/src/zope/interface/registry.py
===================================================================
--- zope.interface/trunk/src/zope/interface/registry.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/registry.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -13,9 +13,6 @@
 ##############################################################################
 """Basic components support
 """
-import sys
-import types
-
 try:
     from zope.event import notify
 except ImportError: #pragma NO COVER
@@ -33,30 +30,20 @@
 
 from zope.interface.interface import Interface
 from zope.interface.declarations import implementedBy
-from zope.interface.declarations import implements
-from zope.interface.declarations import implementsOnly
+from zope.interface.declarations import implementer
+from zope.interface.declarations import implementer_only
 from zope.interface.declarations import providedBy
-from zope.interface.declarations import implementer # required by py3k fixers
-from zope.interface.declarations import implementer_only # req by py3k fixers
 from zope.interface.adapter import AdapterRegistry
+from zope.interface._compat import _u
+from zope.interface._compat import CLASS_TYPES
+from zope.interface._compat import STRING_TYPES
 
-if sys.version_info[0] == 3: #pragma NO COVER
-    def _u(s):
-        return s
-    class_types = type
-    string_types = (str,)
-else:
-    def _u(s):
-        return unicode(s, 'unicode_escape')
-    class_types = (type, types.ClassType)
-    string_types = (basestring,)
 
+ at implementer(IComponents)
 class Components(object):
 
-    implements(IComponents)
-
     def __init__(self, name='', bases=()):
-        assert isinstance(name, string_types)
+        assert isinstance(name, STRING_TYPES)
         self.__name__ = name
         self._init_registries()
         self._init_registrations()
@@ -428,7 +415,7 @@
         if r is None:
             r = Interface
         elif not ISpecification.providedBy(r):
-            if isinstance(r, class_types):
+            if isinstance(r, CLASS_TYPES):
                 r = implementedBy(r)
             else:
                 raise TypeError("Required specification must be a "
@@ -438,10 +425,9 @@
     return tuple(result)
 
 
+ at implementer(IUtilityRegistration)
 class UtilityRegistration(object):
 
-    implements(IUtilityRegistration)
-
     def __init__(self, registry, provided, name, component, doc, factory=None):
         (self.registry, self.provided, self.name, self.component, self.info,
          self.factory
@@ -477,10 +463,9 @@
     def __ge__(self, other):
         return repr(self) >= repr(other)
 
+ at implementer(IAdapterRegistration)
 class AdapterRegistration(object):
 
-    implements(IAdapterRegistration)
-
     def __init__(self, registry, required, provided, name, component, doc):
         (self.registry, self.required, self.provided, self.name,
          self.factory, self.info
@@ -516,14 +501,14 @@
     def __ge__(self, other):
         return repr(self) >= repr(other)
 
+ at implementer_only(ISubscriptionAdapterRegistration)
 class SubscriptionRegistration(AdapterRegistration):
+    pass
 
-    implementsOnly(ISubscriptionAdapterRegistration)
 
+ at implementer_only(IHandlerRegistration)
 class HandlerRegistration(AdapterRegistration):
 
-    implementsOnly(IHandlerRegistration)
-
     def __init__(self, registry, required, name, handler, doc):
         (self.registry, self.required, self.name, self.handler, self.info
          ) = registry, required, name, handler, doc

Modified: zope.interface/trunk/src/zope/interface/tests/test_adapter.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_adapter.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/tests/test_adapter.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -893,12 +893,13 @@
         self.failUnless(result is _expected)
 
     def test_queryMultiAdaptor_lookup_miss(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass('IFoo')
         IBar = InterfaceClass('IBar', IFoo)
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         registry = self._makeRegistry()
         subr = self._makeSubregistry()
@@ -915,12 +916,13 @@
         self.failUnless(result is _default)
 
     def test_queryMultiAdaptor_factory_miss(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass('IFoo')
         IBar = InterfaceClass('IBar', IFoo)
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         registry = self._makeRegistry(IFoo, IBar)
         subr = self._makeSubregistry()
@@ -943,12 +945,13 @@
         self.assertEqual(_called_with, [foo])
 
     def test_queryMultiAdaptor_factory_hit(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass('IFoo')
         IBar = InterfaceClass('IBar', IFoo)
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         registry = self._makeRegistry(IFoo, IBar)
         subr = self._makeSubregistry()
@@ -1111,7 +1114,10 @@
         IBar = InterfaceClass('IBar', IFoo)
         registry = self._makeRegistry(IFoo, IBar)
         subr = self._makeSubregistry()
-        _exp1, _exp2 = object(), object()
+        class Foo(object):
+            def __lt__(self, other):
+                return True
+        _exp1, _exp2 = Foo(), Foo()
         subr._subscribers = [ #utilities, single adapters
             {},
             {IFoo: {IBar: {'': (_exp1, _exp2)}}},
@@ -1123,12 +1129,13 @@
         self.assertEqual(sorted(result), sorted([_exp1, _exp2]))
 
     def test_subscribers_wo_provided(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass('IFoo')
         IBar = InterfaceClass('IBar', IFoo)
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         registry = self._makeRegistry(IFoo, IBar)
         registry = self._makeRegistry(IFoo, IBar)
@@ -1151,12 +1158,13 @@
         self.assertEqual(_called, {'_factory1': [foo], '_factory2': [foo]})
 
     def test_subscribers_w_provided(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass('IFoo')
         IBar = InterfaceClass('IBar', IFoo)
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         registry = self._makeRegistry(IFoo, IBar)
         registry = self._makeRegistry(IFoo, IBar)
@@ -1228,7 +1236,7 @@
         self.failUnless(derived2._changed is orig)
 
 
-class Test_utils(unittest.TestCase):
+class Test_utils(_SilencePy3Deprecations):
 
     def test__convert_None_to_Interface_w_None(self):
         from zope.interface.adapter import _convert_None_to_Interface
@@ -1241,13 +1249,18 @@
         self.failUnless(_convert_None_to_Interface(other) is other)
 
     def test__normalize_name_str(self):
+        import sys
         from zope.interface.adapter import _normalize_name
-        STR = 'str'
-        self.assertEqual(_normalize_name(STR), unicode(STR))
+        STR = b'str'
+        if sys.version_info[0] < 3:
+            self.assertEqual(_normalize_name(STR), unicode(STR))
+        else:
+            self.assertEqual(_normalize_name(STR), str(STR, 'ascii'))
 
     def test__normalize_name_unicode(self):
         from zope.interface.adapter import _normalize_name
-        USTR = u'ustr'
+        from zope.interface._compat import _u
+        USTR = _u('ustr')
         self.assertEqual(_normalize_name(USTR), USTR)
 
     def test__normalize_name_other(self):

Modified: zope.interface/trunk/src/zope/interface/tests/test_advice.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_advice.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/tests/test_advice.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -28,16 +28,33 @@
 import unittest
 import sys
 
-class FrameInfoTest(unittest.TestCase):
+from zope.interface._compat import _skip_under_py2
+from zope.interface._compat import _skip_under_py3k
 
+
+class _SilencePy3Deprecations(unittest.TestCase):
+    # silence deprecation warnings under py3
+
+    def failUnless(self, expr):
+        # St00pid speling.
+        return self.assertTrue(expr)
+
+    def failIf(self, expr):
+        # St00pid speling.
+        return self.assertFalse(expr)
+
+
+class FrameInfoTest(_SilencePy3Deprecations):
+
     def test_w_module(self):
         from zope.interface.tests import advisory_testing
         (kind, module,
          f_locals, f_globals) = advisory_testing.moduleLevelFrameInfo
-        self.assertEquals(kind, "module")
+        self.assertEqual(kind, "module")
         for d in module.__dict__, f_locals, f_globals:
-            self.assert_(d is advisory_testing.my_globals)
+            self.failUnless(d is advisory_testing.my_globals)
 
+    @_skip_under_py3k
     def test_w_ClassicClass(self):
         from zope.interface.tests import advisory_testing
         if advisory_testing.ClassicClass is None:
@@ -46,11 +63,12 @@
          module,
          f_locals,
          f_globals) = advisory_testing.ClassicClass.classLevelFrameInfo
-        self.assertEquals(kind, "class")
+        self.assertEqual(kind, "class")
 
-        self.assert_(f_locals is advisory_testing.ClassicClass.__dict__)  # ???
+        self.failUnless(
+            f_locals is advisory_testing.ClassicClass.__dict__)  # ???
         for d in module.__dict__, f_globals:
-            self.assert_(d is advisory_testing.my_globals)
+            self.failUnless(d is advisory_testing.my_globals)
 
     def test_w_NewStyleClass(self):
         from zope.interface.tests import advisory_testing
@@ -58,28 +76,28 @@
          module,
          f_locals,
          f_globals) = advisory_testing.NewStyleClass.classLevelFrameInfo
-        self.assertEquals(kind, "class")
+        self.assertEqual(kind, "class")
 
         for d in module.__dict__, f_globals:
-            self.assert_(d is advisory_testing.my_globals)
+            self.failUnless(d is advisory_testing.my_globals)
 
     def test_inside_function_call(self):
         from zope.interface.advice import getFrameInfo
         kind, module, f_locals, f_globals = getFrameInfo(sys._getframe())
-        self.assertEquals(kind, "function call")
-        self.assert_(f_locals is locals()) # ???
+        self.assertEqual(kind, "function call")
+        self.failUnless(f_locals is locals()) # ???
         for d in module.__dict__, f_globals:
-            self.assert_(d is globals())
+            self.failUnless(d is globals())
 
     def test_inside_exec(self):
         from zope.interface.advice import getFrameInfo
         _globals = {'getFrameInfo': getFrameInfo}
         _locals = {}
-        exec _FUNKY_EXEC in _globals, _locals
-        self.assertEquals(_locals['kind'], "exec")
-        self.assert_(_locals['f_locals'] is _locals)
-        self.assert_(_locals['module'] is None)
-        self.assert_(_locals['f_globals'] is _globals)
+        exec(_FUNKY_EXEC, _globals, _locals)
+        self.assertEqual(_locals['kind'], "exec")
+        self.failUnless(_locals['f_locals'] is _locals)
+        self.failUnless(_locals['module'] is None)
+        self.failUnless(_locals['f_globals'] is _globals)
 
 
 _FUNKY_EXEC = """\
@@ -87,8 +105,9 @@
 kind, module, f_locals, f_globals = getFrameInfo(sys._getframe())
 """
 
-class AdviceTests(unittest.TestCase):
+class AdviceTests(_SilencePy3Deprecations):
 
+    @_skip_under_py3k
     def test_order(self):
         from zope.interface.tests.advisory_testing import ping
         log = []
@@ -99,10 +118,10 @@
 
         # Strip the list nesting
         for i in 1, 2, 3:
-            self.assert_(isinstance(Foo, list))
+            self.failUnless(isinstance(Foo, list))
             Foo, = Foo
 
-        self.assertEquals(log, [(1, Foo), (2, [Foo]), (3, [[Foo]])])
+        self.assertEqual(log, [(1, Foo), (2, [Foo]), (3, [[Foo]])])
 
     def TODOtest_outside(self):
         from zope.interface.tests.advisory_testing import ping
@@ -116,6 +135,7 @@
                 "Should have detected advice outside class body"
             )
 
+    @_skip_under_py3k
     def test_single_explicit_meta(self):
         from zope.interface.tests.advisory_testing import ping
 
@@ -127,9 +147,10 @@
             ping([],1)
 
         Concrete, = Concrete
-        self.assert_(Concrete.__class__ is Metaclass)
+        self.failUnless(Concrete.__class__ is Metaclass)
 
 
+    @_skip_under_py3k
     def test_mixed_metas(self):
         from zope.interface.tests.advisory_testing import ping
 
@@ -161,28 +182,216 @@
             __metaclass__ = Metaclass3
             ping([], 1)
 
-        self.assert_(isinstance(Derived, list))
+        self.failUnless(isinstance(Derived, list))
         Derived, = Derived
-        self.assert_(isinstance(Derived, Metaclass3))
+        self.failUnless(isinstance(Derived, Metaclass3))
 
-    def test_meta_of_class(self):
+    @_skip_under_py3k
+    def test_meta_no_bases(self):
+        from zope.interface.tests.advisory_testing import ping
+        try:
+            from types import ClassType
+        except ImportError:
+            return
+        class Thing:
+            ping([], 1)
+        klass, = Thing # unpack list created by pong
+        self.assertEqual(type(klass), ClassType)
+
+
+class Test_isClassAdvisor(_SilencePy3Deprecations):
+
+    def _callFUT(self, *args, **kw):
+        from zope.interface.advice import isClassAdvisor
+        return isClassAdvisor(*args, **kw)
+
+    def test_w_non_function(self):
+        self.assertEqual(self._callFUT(self), False)
+
+    def test_w_normal_function(self):
+        def foo():
+            pass
+        self.assertEqual(self._callFUT(foo), False)
+
+    def test_w_advisor_function(self):
+        def bar():
+            pass
+        bar.previousMetaclass = object()
+        self.assertEqual(self._callFUT(bar), True)
+
+
+class Test_determineMetaclass(_SilencePy3Deprecations):
+
+    def _callFUT(self, *args, **kw):
         from zope.interface.advice import determineMetaclass
+        return determineMetaclass(*args, **kw)
 
+    @_skip_under_py3k
+    def test_empty(self):
+        from types import ClassType
+        self.assertEqual(self._callFUT(()), ClassType)
+
+    def test_empty_w_explicit_metatype(self):
+        class Meta(type):
+            pass
+        self.assertEqual(self._callFUT((), Meta), Meta)
+
+    def test_single(self):
+        class Meta(type):
+            pass
+        self.assertEqual(self._callFUT((Meta,)), type)
+
+    @_skip_under_py3k
+    def test_meta_of_class(self):
         class Metameta(type):
             pass
 
         class Meta(type):
             __metaclass__ = Metameta
 
-        self.assertEquals(determineMetaclass((Meta, type)), Metameta)
+        self.assertEqual(self._callFUT((Meta, type)), Metameta)
 
+    @_skip_under_py2
+    def test_meta_of_class_py3k(self):
+        # Work around SyntaxError under Python2.
+        EXEC = '\n'.join([
+        'class Metameta(type):',
+        '    pass',
+        'class Meta(type, metaclass=Metameta):',
+        '    pass',
+        ])
+        globs = {}
+        exec(EXEC, globs)
+        Meta = globs['Meta']
+        Metameta = globs['Metameta']
 
+        self.assertEqual(self._callFUT((Meta, type)), Metameta)
+
+    @_skip_under_py3k
+    def test_multiple_in_hierarchy(self):
+        class Meta_A(type):
+            pass
+        class Meta_B(Meta_A):
+            pass
+        class A(type):
+            __metaclass__ = Meta_A
+        class B(type):
+            __metaclass__ = Meta_B
+        self.assertEqual(self._callFUT((A, B,)), Meta_B)
+
+    @_skip_under_py2
+    def test_multiple_in_hierarchy_py3k(self):
+        # Work around SyntaxError under Python2.
+        EXEC = '\n'.join([
+        'class Meta_A(type):',
+        '    pass',
+        'class Meta_B(Meta_A):',
+        '    pass',
+        'class A(type, metaclass=Meta_A):',
+        '    pass',
+        'class B(type, metaclass=Meta_B):',
+        '    pass',
+        ])
+        globs = {}
+        exec(EXEC, globs)
+        Meta_A = globs['Meta_A']
+        Meta_B = globs['Meta_B']
+        A = globs['A']
+        B = globs['B']
+        self.assertEqual(self._callFUT((A, B)), Meta_B)
+
+    @_skip_under_py3k
+    def test_multiple_not_in_hierarchy(self):
+        class Meta_A(type):
+            pass
+        class Meta_B(type):
+            pass
+        class A(type):
+            __metaclass__ = Meta_A
+        class B(type):
+            __metaclass__ = Meta_B
+        self.assertRaises(TypeError, self._callFUT, (A, B,))
+
+    @_skip_under_py2
+    def test_multiple_not_in_hierarchy_py3k(self):
+        # Work around SyntaxError under Python2.
+        EXEC = '\n'.join([
+        'class Meta_A(type):',
+        '    pass',
+        'class Meta_B(type):',
+        '    pass',
+        'class A(type, metaclass=Meta_A):',
+        '    pass',
+        'class B(type, metaclass=Meta_B):',
+        '    pass',
+        ])
+        globs = {}
+        exec(EXEC, globs)
+        Meta_A = globs['Meta_A']
+        Meta_B = globs['Meta_B']
+        A = globs['A']
+        B = globs['B']
+        self.assertRaises(TypeError, self._callFUT, (A, B))
+
+
+class Test_minimalBases(_SilencePy3Deprecations):
+
+    def _callFUT(self, klasses):
+        from zope.interface.advice import minimalBases
+        return minimalBases(klasses)
+
+    def test_empty(self):
+        self.assertEqual(self._callFUT([]), [])
+
+    @_skip_under_py3k
+    def test_w_oldstyle_meta(self):
+        class C:
+            pass
+        self.assertEqual(self._callFUT([type(C)]), [])
+
+    @_skip_under_py3k
+    def test_w_oldstyle_class(self):
+        class C:
+            pass
+        self.assertEqual(self._callFUT([C]), [C])
+
+    def test_w_newstyle_meta(self):
+        self.assertEqual(self._callFUT([type]), [type])
+
+    def test_w_newstyle_class(self):
+        class C(object):
+            pass
+        self.assertEqual(self._callFUT([C]), [C])
+
+    def test_simple_hierarchy_skips_implied(self):
+        class A(object):
+            pass
+        class B(A):
+            pass
+        class C(B):
+            pass
+        class D(object):
+            pass
+        self.assertEqual(self._callFUT([A, B, C]), [C])
+        self.assertEqual(self._callFUT([A, C]), [C])
+        self.assertEqual(self._callFUT([B, C]), [C])
+        self.assertEqual(self._callFUT([A, B]), [B])
+        self.assertEqual(self._callFUT([D, B, D]), [B, D])
+
+    def test_repeats_kicked_to_end_of_queue(self):
+        class A(object):
+            pass
+        class B(object):
+            pass
+        self.assertEqual(self._callFUT([A, B, A]), [B, A])
+
+
+
 def test_suite():
-    if sys.version[0] == '2':
-        return unittest.TestSuite((
-            unittest.makeSuite(FrameInfoTest),
-            unittest.makeSuite(AdviceTests),
-        ))
-    else:
-        # Advise metaclasses doesn't work in Python 3
-        return TestSuite([])
+    return unittest.TestSuite((
+        unittest.makeSuite(FrameInfoTest),
+        unittest.makeSuite(AdviceTests),
+        unittest.makeSuite(Test_isClassAdvisor),
+        unittest.makeSuite(Test_determineMetaclass),
+        unittest.makeSuite(Test_minimalBases),
+    ))

Modified: zope.interface/trunk/src/zope/interface/tests/test_declarations.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_declarations.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/tests/test_declarations.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -15,7 +15,9 @@
 """
 import unittest
 
+from zope.interface._compat import _skip_under_py3k
 
+
 class _SilencePy3Deprecations(unittest.TestCase):
     # silence deprecation warnings under py3
 
@@ -26,6 +28,32 @@
     def failIf(self, expr):
         # St00pid speling.
         return self.assertFalse(expr)
+
+
+class _Py3ClassAdvice(object):
+
+    def _run_generated_code(self, code, globs, locs,
+                            fails_under_py3k=True,
+                            warnings_under_py2=1):
+        import warnings
+        from zope.interface._compat import PYTHON3
+        with warnings.catch_warnings(record=True) as log:
+            warnings.resetwarnings()
+            if not PYTHON3:
+                exec(code, globs, locs)
+                if warnings_under_py2:
+                    self.assertEqual(len(log), warnings_under_py2)
+                    for entry in log:
+                        self.assertEqual(entry.category, DeprecationWarning)
+                return True
+            else:
+                try:
+                    exec(code, globs, locs)
+                except TypeError:
+                    return False
+                else:
+                    if fails_under_py3k:
+                        self.fail("Didn't raise TypeError")
  
 
 class DeclarationTests(_SilencePy3Deprecations):
@@ -250,8 +278,9 @@
         foo = Foo()
         foo.__implemented__ = None
         reg = object()
-        specs = {foo: reg}
-        with _Monkey(declarations, BuiltinImplementationSpecifications=specs):
+        with _MonkeyDict(declarations,
+                         'BuiltinImplementationSpecifications') as specs:
+            specs[foo] = reg
             self.failUnless(self._callFUT(foo) is reg)
 
     def test_dictless_w_existing_Implements(self):
@@ -282,22 +311,27 @@
     def test_builtins_added_to_cache(self):
         from zope.interface import declarations
         from zope.interface.declarations import Implements
-        specs = {}
-        with _Monkey(declarations, BuiltinImplementationSpecifications=specs):
+        from zope.interface._compat import _BUILTINS
+        with _MonkeyDict(declarations,
+                         'BuiltinImplementationSpecifications') as specs:
             self.assertEqual(list(self._callFUT(tuple)), [])
             self.assertEqual(list(self._callFUT(list)), [])
             self.assertEqual(list(self._callFUT(dict)), [])
-        for typ in (tuple, list, dict):
-            spec = specs[typ]
-            self.failUnless(isinstance(spec, Implements))
-            self.assertEqual(repr(spec),
-                             '<implementedBy __builtin__.%s>' % typ.__name__)
+            for typ in (tuple, list, dict):
+                spec = specs[typ]
+                self.failUnless(isinstance(spec, Implements))
+                self.assertEqual(repr(spec),
+                                '<implementedBy %s.%s>'
+                                    % (_BUILTINS, typ.__name__))
 
     def test_builtins_w_existing_cache(self):
         from zope.interface import declarations
         t_spec, l_spec, d_spec = object(), object(), object()
-        specs = {tuple: t_spec, list: l_spec, dict: d_spec}
-        with _Monkey(declarations, BuiltinImplementationSpecifications=specs):
+        with _MonkeyDict(declarations,
+                         'BuiltinImplementationSpecifications') as specs:
+            specs[tuple] = t_spec
+            specs[list] = l_spec
+            specs[dict] = d_spec
             self.failUnless(self._callFUT(tuple) is t_spec)
             self.failUnless(self._callFUT(list) is l_spec)
             self.failUnless(self._callFUT(dict) is d_spec)
@@ -610,12 +644,42 @@
 
 # Test '_implements' by way of 'implements{,Only}', its only callers.
 
-class Test_implementsOnly(_SilencePy3Deprecations):
+class Test_implementsOnly(_SilencePy3Deprecations, _Py3ClassAdvice):
 
     def _getFUT(self):
         from zope.interface.declarations import implementsOnly
         return implementsOnly
 
+    def test_simple(self):
+        import warnings
+        from zope.interface.declarations import implementsOnly
+        from zope.interface._compat import PYTHON3
+        from zope.interface.interface import InterfaceClass
+        IFoo = InterfaceClass("IFoo")
+        globs = {'implementsOnly': implementsOnly,
+                 'IFoo': IFoo,
+                }
+        locs = {}
+        CODE = "\n".join([
+            'class Foo(object):'
+            '    implementsOnly(IFoo)',
+            ])
+        with warnings.catch_warnings(record=True) as log:
+            warnings.resetwarnings()
+            try:
+                exec(CODE, globs, locs)
+            except TypeError:
+                if not PYTHON3:
+                    raise
+            else:
+                if PYTHON3:
+                    self.fail("Didn't raise TypeError")
+                Foo = locs['Foo']
+                spec = Foo.__implemented__
+                self.assertEqual(list(spec), [IFoo])
+                self.assertEqual(len(log), 1)
+                self.assertEqual(log[0].category, DeprecationWarning)
+
     def test_called_once_from_class_w_bases(self):
         from zope.interface.declarations import implements
         from zope.interface.declarations import implementsOnly
@@ -634,19 +698,20 @@
             'class Bar(Foo):'
             '    implementsOnly(IBar)',
             ])
-        # XXX need six-ish majyk here :(
-        exec CODE in globs, locs
-        Bar = locs['Bar']
-        spec = Bar.__implemented__
-        self.assertEqual(list(spec), [IBar])
+        if self._run_generated_code(CODE, globs, locs, warnings_under_py2=2):
+            Bar = locs['Bar']
+            spec = Bar.__implemented__
+            self.assertEqual(list(spec), [IBar])
 
-class Test_implements(_SilencePy3Deprecations):
 
+class Test_implements(_SilencePy3Deprecations, _Py3ClassAdvice):
+
     def _getFUT(self):
         from zope.interface.declarations import implements
         return implements
 
     def test_called_from_function(self):
+        import warnings
         from zope.interface.declarations import implements
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
@@ -656,14 +721,19 @@
             'def foo():',
             '    implements(IFoo)'
             ])
-        # XXX need six-ish majyk here :(
-        exec CODE in globs, locs
-        foo = locs['foo']
-        self.assertRaises(TypeError, foo)
+        if self._run_generated_code(CODE, globs, locs, False, 0):
+            foo = locs['foo']
+            with warnings.catch_warnings(record=True) as log:
+                warnings.resetwarnings()
+                self.assertRaises(TypeError, foo)
+                self.assertEqual(len(log), 1)
+                self.assertEqual(log[0].category, DeprecationWarning)
 
     def test_called_twice_from_class(self):
+        import warnings
         from zope.interface.declarations import implements
         from zope.interface.interface import InterfaceClass
+        from zope.interface._compat import PYTHON3
         IFoo = InterfaceClass("IFoo")
         IBar = InterfaceClass("IBar")
         globs = {'implements': implements, 'IFoo': IFoo, 'IBar': IBar}
@@ -673,13 +743,17 @@
             '    implements(IFoo)',
             '    implements(IBar)',
             ])
-        # XXX need six-ish majyk here :(
-        try:
-            exec CODE in globs, locs
-        except TypeError:
-            pass
-        else:
-            self.fail("Didn't raise TypeError")
+        with warnings.catch_warnings(record=True) as log:
+            warnings.resetwarnings()
+            try:
+                exec(CODE, globs, locs)
+            except TypeError:
+                if not PYTHON3:
+                    self.assertEqual(len(log), 2)
+                    for entry in log:
+                        self.assertEqual(entry.category, DeprecationWarning)
+            else:
+                self.fail("Didn't raise TypeError")
 
     def test_called_once_from_class(self):
         from zope.interface.declarations import implements
@@ -691,11 +765,10 @@
             'class Foo(object):',
             '    implements(IFoo)',
             ])
-        # XXX need six-ish majyk here :(
-        exec CODE in globs, locs
-        Foo = locs['Foo']
-        spec = Foo.__implemented__
-        self.assertEqual(list(spec), [IFoo])
+        if self._run_generated_code(CODE, globs, locs):
+            Foo = locs['Foo']
+            spec = Foo.__implemented__
+            self.assertEqual(list(spec), [IFoo])
 
 
 class ProvidesClassTests(_SilencePy3Deprecations):
@@ -806,7 +879,9 @@
         self.failUnless(isinstance(Foo.__provides__, ClassProvides))
         self.assertEqual(list(Foo.__provides__), [IFoo])
 
+    @_skip_under_py3k
     def test_w_non_descriptor_aware_metaclass(self):
+        # There are no non-descriptor-aware types in Py3k
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
         class MetaClass(type):
@@ -913,11 +988,12 @@
         self.assertEqual(list(obj.__provides__), [IFoo])
 
     def test_w_iface_implemented_by_class(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         obj = Foo()
         self.assertRaises(ValueError, self._callFUT, obj, IFoo)
 
@@ -985,23 +1061,25 @@
         return self._getTargetClass()(*args, **kw)
 
     def test_w_simple_metaclass(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
         IBar = InterfaceClass("IBar")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar)
         self.failUnless(Foo.__provides__ is cp)
         self.assertEqual(list(Foo().__provides__), [IFoo])
 
     def test___reduce__(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
         IBar = InterfaceClass("IBar")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar)
         self.assertEqual(cp.__reduce__(),
                          (self._getTargetClass(), (Foo, type(Foo), IBar)))
@@ -1020,11 +1098,12 @@
         self.assertEqual(list(self._callFUT(foo)), [])
 
     def test_w_declarations_in_class_but_not_instance(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         self.assertEqual(list(self._callFUT(foo)), [])
 
@@ -1040,26 +1119,29 @@
 
     def test_w_declarations_in_instance_and_class(self):
         from zope.interface.declarations import directlyProvides
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
         IBar = InterfaceClass("IBar")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         directlyProvides(foo, IBar)
         self.assertEqual(list(self._callFUT(foo)), [IBar])
 
 
-class Test_classProvides(_SilencePy3Deprecations):
+class Test_classProvides(_SilencePy3Deprecations, _Py3ClassAdvice):
 
     def _getFUT(self):
         from zope.interface.declarations import classProvides
         return classProvides
 
     def test_called_from_function(self):
+        import warnings
         from zope.interface.declarations import classProvides
         from zope.interface.interface import InterfaceClass
+        from zope.interface._compat import PYTHON3
         IFoo = InterfaceClass("IFoo")
         globs = {'classProvides': classProvides, 'IFoo': IFoo}
         locs = {}
@@ -1067,14 +1149,20 @@
             'def foo():',
             '    classProvides(IFoo)'
             ])
-        # XXX need six-ish majyk here :(
-        exec CODE in globs, locs
+        exec(CODE, globs, locs)
         foo = locs['foo']
-        self.assertRaises(TypeError, foo)
+        with warnings.catch_warnings(record=True) as log:
+            warnings.resetwarnings()
+            self.assertRaises(TypeError, foo)
+            if not PYTHON3:
+                self.assertEqual(len(log), 1)
+                self.assertEqual(log[0].category, DeprecationWarning)
 
     def test_called_twice_from_class(self):
+        import warnings
         from zope.interface.declarations import classProvides
         from zope.interface.interface import InterfaceClass
+        from zope.interface._compat import PYTHON3
         IFoo = InterfaceClass("IFoo")
         IBar = InterfaceClass("IBar")
         globs = {'classProvides': classProvides, 'IFoo': IFoo, 'IBar': IBar}
@@ -1084,13 +1172,17 @@
             '    classProvides(IFoo)',
             '    classProvides(IBar)',
             ])
-        # XXX need six-ish majyk here :(
-        try:
-            exec CODE in globs, locs
-        except TypeError:
-            pass
-        else:
-            self.fail("Didn't raise TypeError")
+        with warnings.catch_warnings(record=True) as log:
+            warnings.resetwarnings()
+            try:
+                exec(CODE, globs, locs)
+            except TypeError:
+                if not PYTHON3:
+                    self.assertEqual(len(log), 2)
+                    for entry in log:
+                        self.assertEqual(entry.category, DeprecationWarning)
+            else:
+                self.fail("Didn't raise TypeError")
 
     def test_called_once_from_class(self):
         from zope.interface.declarations import classProvides
@@ -1102,13 +1194,11 @@
             'class Foo(object):',
             '    classProvides(IFoo)',
             ])
-        # XXX need six-ish majyk here :(
-        exec CODE in globs, locs
-        Foo = locs['Foo']
-        spec = Foo.__providedBy__
-        self.assertEqual(list(spec), [IFoo])
+        if self._run_generated_code(CODE, globs, locs):
+            Foo = locs['Foo']
+            spec = Foo.__providedBy__
+            self.assertEqual(list(spec), [IFoo])
 
-
 # Test _classProvides_advice through classProvides, its only caller.
 
 
@@ -1149,8 +1239,7 @@
             'def foo():',
             '    moduleProvides(IFoo)'
             ])
-        # XXX need six-ish majyk here :(
-        exec CODE in globs, locs
+        exec(CODE, globs, locs)
         foo = locs['foo']
         self.assertRaises(TypeError, foo)
 
@@ -1160,13 +1249,13 @@
         IFoo = InterfaceClass("IFoo")
         globs = {'__name__': 'zope.interface.tests.foo',
                  'moduleProvides': moduleProvides, 'IFoo': IFoo}
+        locs = {}
         CODE = "\n".join([
             'class Foo(object):',
             '    moduleProvides(IFoo)',
             ])
         try:
-            # XXX need six-ish majyk here :(
-            exec CODE in globs
+            exec(CODE, globs, locs)
         except TypeError:
             pass
         else:
@@ -1181,8 +1270,7 @@
         CODE = "\n".join([
             'moduleProvides(IFoo)',
             ])
-        # XXX need six-ish majyk here :(
-        exec CODE in globs
+        exec(CODE, globs)
         spec = globs['__provides__']
         self.assertEqual(list(spec), [IFoo])
 
@@ -1192,13 +1280,13 @@
         IFoo = InterfaceClass("IFoo")
         globs = {'__name__': 'zope.interface.tests.foo',
                  'moduleProvides': moduleProvides, 'IFoo': IFoo}
+        locs = {}
         CODE = "\n".join([
             'moduleProvides(IFoo)',
             'moduleProvides(IFoo)',
             ])
         try:
-            # XXX need six-ish majyk here :(
-            exec CODE in globs
+            exec(CODE, globs)
         except TypeError:
             pass
         else:
@@ -1257,11 +1345,12 @@
         self.assertEqual(list(spec), [IFoo])
 
     def test_wo_provides_on_class_w_implements(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         spec = self._callFUT(foo)
         self.assertEqual(list(spec), [IFoo])
@@ -1315,11 +1404,12 @@
         self.assertEqual(list(spec), [])
 
     def test_w_providedBy_invalid_spec_class_w_implements(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         foo.__providedBy__ = object()
         spec = self._callFUT(foo)
@@ -1345,11 +1435,12 @@
         self.failUnless(spec is expected)
 
     def test_w_providedBy_invalid_spec_w_provides_same_provides_on_class(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         foo = Foo()
         foo.__providedBy__ = object()
         foo.__provides__ = Foo.__provides__ = object()
@@ -1386,13 +1477,14 @@
         self.assertEqual(list(Foo.__providedBy__), [IFoo])
 
     def test_accessed_via_inst_wo_provides(self):
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.declarations import Provides
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
         IBar = InterfaceClass("IBar")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         Foo.__provides__ = Provides(Foo, IBar)
         Foo.__providedBy__ = self._makeOne()
         foo = Foo()
@@ -1400,14 +1492,15 @@
 
     def test_accessed_via_inst_w_provides(self):
         from zope.interface.declarations import directlyProvides
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.declarations import Provides
         from zope.interface.interface import InterfaceClass
         IFoo = InterfaceClass("IFoo")
         IBar = InterfaceClass("IBar")
         IBaz = InterfaceClass("IBaz")
+        @implementer(IFoo)
         class Foo(object):
-            implements(IFoo)
+            pass
         Foo.__provides__ = Provides(Foo, IBar)
         Foo.__providedBy__ = self._makeOne()
         foo = Foo()
@@ -1443,6 +1536,23 @@
             setattr(self.module, key, value)
 
 
+class _MonkeyDict(object):
+    # context-manager for restoring a dict w/in a module in the scope of a test.
+    def __init__(self, module, attrname, **kw):
+        self.module = module
+        self.target = getattr(module, attrname)
+        self.to_restore = self.target.copy()
+        self.target.clear()
+        self.target.update(kw)
+
+    def __enter__(self):
+        return self.target
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.target.clear()
+        self.target.update(self.to_restore)
+
+
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite(DeclarationTests),

Modified: zope.interface/trunk/src/zope/interface/tests/test_interface.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_interface.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/tests/test_interface.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -119,7 +119,7 @@
         self.assertEqual(element.getName(), self.DEFAULT_NAME)
         self.assertEqual(element.__doc__, '')
         self.assertEqual(element.getDoc(), '')
-        self.assertEqual(element.getTaggedValueTags(), [])
+        self.assertEqual(list(element.getTaggedValueTags()), [])
 
     def test_ctor_no_doc_space_in_name(self):
         element = self._makeOne('An Element')
@@ -141,7 +141,7 @@
     def test_setTaggedValue(self):
         element = self._makeOne()
         element.setTaggedValue('foo', 'bar')
-        self.assertEqual(element.getTaggedValueTags(), ['foo'])
+        self.assertEqual(list(element.getTaggedValueTags()), ['foo'])
         self.assertEqual(element.getTaggedValue('foo'), 'bar')
         self.assertEqual(element.queryTaggedValue('foo'), 'bar')
 
@@ -350,7 +350,7 @@
         spec._v_attrs = 'Foo'
         spec._implied[I] = ()
         spec.changed(spec)
-        self.assert_(getattr(spec, '_v_attrs', self) is self)
+        self.failUnless(getattr(spec, '_v_attrs', self) is self)
         self.failIf(I in spec._implied)
 
 
@@ -408,7 +408,7 @@
         self.assertEqual(inst.__name__, 'ITesting')
         self.assertEqual(inst.__doc__, '')
         self.assertEqual(inst.__bases__, ())
-        self.assertEqual(inst.names(), [])
+        self.assertEqual(list(inst.names()), [])
 
     def test_ctor_attrs_w_invalide_attr_type(self):
         from zope.interface.exceptions import InvalidInterface
@@ -1043,9 +1043,10 @@
         from zope.interface import Attribute
         from zope.interface import Interface
         from zope.interface.verify import verifyClass
+        from zope.interface._compat import _u
 
         class ICheckMe(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 pass
@@ -1063,9 +1064,10 @@
         from zope.interface import Attribute
         from zope.interface import Interface
         from zope.interface.verify import verifyObject
+        from zope.interface._compat import _u
 
         class ICheckMe(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 pass
@@ -1087,14 +1089,15 @@
         class AnInterface(Interface):
             pass
 
-        self.assert_(Interface.providedBy(AnInterface))
+        self.failUnless(Interface.providedBy(AnInterface))
 
     def test_names_simple(self):
         from zope.interface import Attribute
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class ISimple(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 pass
@@ -1104,15 +1107,16 @@
     def test_names_derived(self):
         from zope.interface import Attribute
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class IBase(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 pass
 
         class IDerived(IBase):
-            attr2 = Attribute(u'My attr')
+            attr2 = Attribute(_u('My attr2'))
 
             def method():
                 pass
@@ -1129,9 +1133,10 @@
         from zope.interface import Attribute
         from zope.interface.interface import Method
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class ISimple(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
@@ -1152,15 +1157,16 @@
         from zope.interface import Attribute
         from zope.interface import Interface
         from zope.interface.interface import Method
+        from zope.interface._compat import _u
 
         class IBase(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
 
         class IDerived(IBase):
-            attr2 = Attribute(u'My attr2')
+            attr2 = Attribute(_u('My attr2'))
 
             def method():
                 "My method, overridden"
@@ -1216,9 +1222,10 @@
         from zope.interface import Attribute
         from zope.interface.interface import Method
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class ISimple(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
@@ -1237,15 +1244,16 @@
         from zope.interface import Attribute
         from zope.interface.interface import Method
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class IBase(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
 
         class IDerived(IBase):
-            attr2 = Attribute(u'My attr2')
+            attr2 = Attribute(_u('My attr2'))
 
             def method():
                 "My method, overridden"
@@ -1285,9 +1293,10 @@
         from zope.interface import Attribute
         from zope.interface.interface import Method
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class ISimple(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
@@ -1306,15 +1315,16 @@
         from zope.interface import Attribute
         from zope.interface.interface import Method
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class IBase(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
 
         class IDerived(IBase):
-            attr2 = Attribute(u'My attr2')
+            attr2 = Attribute(_u('My attr2'))
 
             def method():
                 "My method, overridden"
@@ -1353,9 +1363,10 @@
     def test___contains__simple(self):
         from zope.interface import Attribute
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class ISimple(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
@@ -1366,15 +1377,16 @@
     def test___contains__derived(self):
         from zope.interface import Attribute
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class IBase(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
 
         class IDerived(IBase):
-            attr2 = Attribute(u'My attr2')
+            attr2 = Attribute(_u('My attr2'))
 
             def method():
                 "My method, overridden"
@@ -1398,9 +1410,10 @@
     def test___iter__simple(self):
         from zope.interface import Attribute
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class ISimple(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
@@ -1410,15 +1423,16 @@
     def test___iter__derived(self):
         from zope.interface import Attribute
         from zope.interface import Interface
+        from zope.interface._compat import _u
 
         class IBase(Interface):
-            attr = Attribute(u'My attr')
+            attr = Attribute(_u('My attr'))
 
             def method():
                 "My method"
 
         class IDerived(IBase):
-            attr2 = Attribute(u'My attr2')
+            attr2 = Attribute(_u('My attr2'))
 
             def method():
                 "My method, overridden"
@@ -1466,16 +1480,16 @@
         e = []
         try:
             iface.validateInvariants(has_invariant, e)
-        except Invalid, error:
-            self.assertEquals(error.args[0], e)
+        except Invalid as error:
+            self.assertEqual(error.args[0], e)
         else:
             self._assert(0) # validateInvariants should always raise
             # Invalid
-        self.assertEquals(len(e), error_len)
+        self.assertEqual(len(e), error_len)
         msgs = [error.args[0] for error in e]
         msgs.sort()
         for msg in msgs:
-            self.assertEquals(msg, error_msgs.pop(0))
+            self.assertEqual(msg, error_msgs.pop(0))
 
     def test_invariant_simple(self):
         from zope.interface import Attribute
@@ -1552,7 +1566,7 @@
         # for a happy ending, we'll make the invariants happy
         has_invariant.foo = 1
         has_invariant.bar = 2
-        self.assertEquals(IInvariant.validateInvariants(has_invariant), None)
+        self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
 
     def test_invariant_mutandis(self):
         from zope.interface import Attribute
@@ -1603,7 +1617,7 @@
         # for another happy ending, we'll make the invariants happy again
         has_invariant.foo = 1
         has_invariant.bar = 2
-        self.assertEquals(IInvariant.validateInvariants(has_invariant), None)
+        self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
         # clean up
         IInvariant.setTaggedValue('invariants', old_invariants)
 
@@ -1643,7 +1657,7 @@
     def test_invariant_as_decorator(self):
         from zope.interface import Interface
         from zope.interface import Attribute
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface import invariant
         from zope.interface.exceptions import Invalid
 
@@ -1656,8 +1670,8 @@
                 if ob.max < ob.min:
                     raise Invalid('max < min')
 
+        @implementer(IRange)
         class Range(object):
-            implements(IRange)
 
             def __init__(self, min, max):
                 self.min, self.max = min, max
@@ -1666,7 +1680,7 @@
         IRange.validateInvariants(Range(1,1))
         try:
             IRange.validateInvariants(Range(2,1))
-        except Invalid, e:
+        except Invalid as e:
             self.assertEqual(str(e), 'max < min')
 
     def test_taggedValue(self):
@@ -1682,8 +1696,8 @@
         class HasInvariant(object):
             pass
 
-        self.assertEquals(ITagged.getTaggedValue('qux'), 'Spam')
-        self.assert_('qux' in ITagged.getTaggedValueTags())
+        self.assertEqual(ITagged.getTaggedValue('qux'), 'Spam')
+        self.failUnless('qux' in ITagged.getTaggedValueTags())
 
     def test_description_cache_management(self):
         # See https://bugs.launchpad.net/zope.interface/+bug/185974
@@ -1708,13 +1722,13 @@
 
     def test___call___defers_to___conform___(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class I(Interface):
             pass
 
+        @implementer(I)
         class C(object):
-            implements(I)
             def __conform__(self, proto):
                 return 0
 
@@ -1722,16 +1736,17 @@
 
     def test___call___object_implements(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class I(Interface):
             pass
 
+        @implementer(I)
         class C(object):
-            implements(I)
+            pass
 
         c = C()
-        self.assert_(I(c) is c)
+        self.failUnless(I(c) is c)
 
     def test___call___miss_wo_alternate(self):
         from zope.interface import Interface
@@ -1755,7 +1770,7 @@
             pass
 
         c = C()
-        self.assert_(I(c, self) is self)
+        self.failUnless(I(c, self) is self)
 
     def test___call___w_adapter_hook(self):
         from zope.interface import Interface
@@ -1768,8 +1783,6 @@
         def _hit(iface, obj):
             return self
 
-        adapter_hooks[:] = [_miss, _hit]
-
         class I(Interface):
             pass
 
@@ -1777,9 +1790,15 @@
             pass
 
         c = C()
-        self.assert_(I(c) is self)
 
+        old_adapter_hooks = adapter_hooks[:]
+        adapter_hooks[:] = [_miss, _hit]
+        try:
+            self.failUnless(I(c) is self)
+        finally:
+            adapter_hooks[:] = old_adapter_hooks
 
+
 class AttributeTests(ElementTests):
 
     DEFAULT_NAME = 'TestAttribute'
@@ -1810,7 +1829,7 @@
         method = self._makeOne()
         try:
             method()
-        except BrokenImplementation, e:
+        except BrokenImplementation as e:
             self.assertEqual(e.interface, None)
             self.assertEqual(e.name, self.DEFAULT_NAME)
         else:
@@ -1864,7 +1883,7 @@
         self.assertEqual(method.getName(), '_func')
         self.assertEqual(method.getDoc(), 'DOCSTRING')
         self.assertEqual(method.interface, None)
-        self.assertEqual(method.getTaggedValueTags(), [])
+        self.assertEqual(list(method.getTaggedValueTags()), [])
         info = method.getSignatureInfo()
         self.assertEqual(list(info['positional']), [])
         self.assertEqual(list(info['required']), [])
@@ -1975,7 +1994,7 @@
         self.assertEqual(method.getName(), 'bar')
         self.assertEqual(method.getDoc(), 'DOCSTRING')
         self.assertEqual(method.interface, None)
-        self.assertEqual(method.getTaggedValueTags(), [])
+        self.assertEqual(list(method.getTaggedValueTags()), [])
         info = method.getSignatureInfo()
         self.assertEqual(list(info['positional']), [])
         self.assertEqual(list(info['required']), [])
@@ -1995,6 +2014,21 @@
         self.assertEqual(info['varargs'], 'args')
         self.assertEqual(info['kwargs'], 'kw')
 
+    def test_w_non_method(self):
+        def foo():
+            "DOCSTRING"
+        method = self._callFUT(foo)
+        self.assertEqual(method.getName(), 'foo')
+        self.assertEqual(method.getDoc(), 'DOCSTRING')
+        self.assertEqual(method.interface, None)
+        self.assertEqual(list(method.getTaggedValueTags()), [])
+        info = method.getSignatureInfo()
+        self.assertEqual(list(info['positional']), [])
+        self.assertEqual(list(info['required']), [])
+        self.assertEqual(info['optional'], {})
+        self.assertEqual(info['varargs'], None)
+        self.assertEqual(info['kwargs'], None)
+
 class DummyDependent(object):
 
     def __init__(self):

Modified: zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/tests/test_odd_declarations.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -20,13 +20,14 @@
 
 from zope.interface.tests import odd
 from zope.interface import Interface
-from zope.interface import implements
+from zope.interface import implementer
 from zope.interface import directlyProvides
 from zope.interface import providedBy
 from zope.interface import directlyProvidedBy
 from zope.interface import classImplements
 from zope.interface import classImplementsOnly
 from zope.interface import implementedBy
+from zope.interface._compat import _skip_under_py3k
 
 class I1(Interface): pass
 class I2(Interface): pass
@@ -121,11 +122,14 @@
         self.failUnless(providedBy(c).extends(I5))
 
     def test_classImplements(self):
+
+        @implementer(I3)
         class A(Odd):
-            implements(I3)
+            pass
 
+        @implementer(I4)
         class B(Odd):
-            implements(I4)
+            pass
 
         class C(A, B):
             pass
@@ -137,11 +141,13 @@
                          ['I1', 'I2', 'I5', 'I3', 'I4'])
 
     def test_classImplementsOnly(self):
+        @implementer(I3)
         class A(Odd):
-            implements(I3)
+            pass
 
+        @implementer(I4)
         class B(Odd):
-            implements(I4)
+            pass
 
         class C(A, B):
             pass
@@ -184,6 +190,7 @@
         directlyProvides(ob, directlyProvidedBy(ob), I2)
         self.failUnless(I2 in providedBy(ob))
 
+    @_skip_under_py3k
     def test_directlyProvides_fails_for_odd_class(self):
         self.assertRaises(TypeError, directlyProvides, C, I5)
 

Modified: zope.interface/trunk/src/zope/interface/tests/test_registry.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_registry.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/tests/test_registry.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -93,7 +93,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -125,7 +125,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -153,7 +153,7 @@
 
     def test_registerUtility_no_provided_available(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         class Foo(object):
@@ -171,7 +171,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         class Foo(object):
@@ -200,7 +200,7 @@
 
     def test_registerUtility_duplicates_existing_reg(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -219,7 +219,7 @@
         from zope.interface.interfaces import Unregistered
         from zope.interface.interfaces import Registered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -257,7 +257,7 @@
 
     def test_registerUtility_w_existing_subscr(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -274,7 +274,7 @@
 
     def test_registerUtility_wo_event(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -302,7 +302,7 @@
 
     def test_unregisterUtility_w_component_miss(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -319,7 +319,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Unregistered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -350,7 +350,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Unregistered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -382,7 +382,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Unregistered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         class Foo(object):
@@ -416,7 +416,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Unregistered
         from zope.interface.registry import UtilityRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         class Foo(object):
@@ -448,7 +448,7 @@
 
     def test_unregisterUtility_w_existing_subscr(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -470,7 +470,7 @@
 
     def test_registeredUtilities_notempty(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         from zope.interface.registry import UtilityRegistration
         class IFoo(InterfaceClass):
             pass
@@ -555,7 +555,7 @@
 
     def test_getUtilitiesFor_hit(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -578,7 +578,7 @@
 
     def test_getAllUtilitiesRegisteredFor_hit(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -595,7 +595,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import AdapterRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -628,7 +628,7 @@
 
     def test_registerAdapter_no_provided_available(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -648,7 +648,7 @@
         from zope.interface.declarations import implementer
         from zope.interface.interfaces import Registered
         from zope.interface.registry import AdapterRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -683,7 +683,7 @@
 
     def test_registerAdapter_no_required_available(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -699,7 +699,7 @@
 
     def test_registerAdapter_w_invalid_required(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -718,7 +718,7 @@
         from zope.interface.interface import Interface
         from zope.interface.interfaces import Registered
         from zope.interface.registry import AdapterRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -751,11 +751,11 @@
 
     def test_registerAdapter_w_required_containing_class(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         from zope.interface.declarations import implementedBy
         from zope.interface.interfaces import Registered
         from zope.interface.registry import AdapterRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -765,8 +765,9 @@
         class _Factory(object):
             def __init__(self, context):
                 self._context = context
+        @implementer(ibar)
         class _Context(object):
-            implements(ibar)
+            pass
         _ctx_impl = implementedBy(_Context)
         comp = self._makeOne()
         _monkey, _events = self._wrapEvents()
@@ -792,7 +793,7 @@
 
     def test_registerAdapter_w_required_containing_junk(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -810,7 +811,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import AdapterRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -845,7 +846,7 @@
 
     def test_registerAdapter_wo_event(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -992,7 +993,7 @@
 
     def test_registeredAdapters_notempty(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         from zope.interface.registry import AdapterRegistration
         class IFoo(InterfaceClass):
             pass
@@ -1236,7 +1237,7 @@
     def test_getAdapters_non_empty(self):
         from zope.interface.declarations import InterfaceClass
         from zope.interface.declarations import implementer
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1270,7 +1271,7 @@
 
     def test_registerSubscriptionAdapter_w_nonblank_name(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1288,7 +1289,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import SubscriptionRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1326,7 +1327,7 @@
         from zope.interface.declarations import implementer
         from zope.interface.interfaces import Registered
         from zope.interface.registry import SubscriptionRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1364,7 +1365,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import SubscriptionRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1400,7 +1401,7 @@
 
     def test_registerSubscriptionAdapter_wo_event(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1423,7 +1424,7 @@
 
     def test_registeredSubscriptionAdapters_notempty(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         from zope.interface.registry import SubscriptionRegistration
         class IFoo(InterfaceClass):
             pass
@@ -1456,7 +1457,7 @@
 
     def test_unregisterSubscriptionAdapter_w_nonblank_name(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1625,20 +1626,21 @@
 
     def test_subscribers_empty(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
         ibar = IFoo('IBar')
         comp = self._makeOne()
+        @implementer(ibar)
         class Bar(object):
-            implements(ibar)
+            pass
         bar = Bar()
         self.assertEqual(list(comp.subscribers((bar,), ifoo)), [])
 
     def test_subscribers_non_empty(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1652,8 +1654,9 @@
         comp = self._makeOne()
         comp.registerSubscriptionAdapter(_Factory, (ibar,), ifoo)
         comp.registerSubscriptionAdapter(_Derived, (ibar,), ifoo)
+        @implementer(ibar)
         class Bar(object):
-            implements(ibar)
+            pass
         bar = Bar()
         subscribers = comp.subscribers((bar,), ifoo)
         def _klassname(x):
@@ -1665,7 +1668,7 @@
 
     def test_registerHandler_w_nonblank_name(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1680,7 +1683,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import HandlerRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1714,7 +1717,7 @@
         from zope.interface.declarations import InterfaceClass
         from zope.interface.interfaces import Registered
         from zope.interface.registry import HandlerRegistration
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1766,7 +1769,7 @@
         comp.registerHandler(_factory1, (ifoo,))
         comp.registerHandler(_factory2, (ifoo,))
         def _factory_name(x):
-            return x.factory.func_code.co_name
+            return x.factory.__code__.co_name
         subscribers = sorted(comp.registeredHandlers(), key=_factory_name)
         self.assertEqual(len(subscribers), 2)
         self.failUnless(isinstance(subscribers[0], HandlerRegistration))
@@ -1782,7 +1785,7 @@
  
     def test_unregisterHandler_w_nonblank_name(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1895,19 +1898,20 @@
 
     def test_handle_empty(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
         comp = self._makeOne()
+        @implementer(ifoo)
         class Bar(object):
-            implements(ifoo)
+            pass
         bar = Bar()
         comp.handle((bar,)) # doesn't raise
 
     def test_handle_non_empty(self):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.declarations import implements
+        from zope.interface.declarations import implementer
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -1920,8 +1924,9 @@
         comp = self._makeOne()
         comp.registerHandler(_factory_1, (ifoo,))
         comp.registerHandler(_factory_2, (ifoo,))
+        @implementer(ifoo)
         class Bar(object):
-            implements(ifoo)
+            pass
         bar = Bar()
         comp.handle(bar)
         self.assertEqual(_called_1, [bar])
@@ -1932,7 +1937,7 @@
 # callers (Component.registerUtility, Component.registerAdapter).
 
 
-class UtilityRegistrationTests(unittest.TestCase):
+class UtilityRegistrationTests(_SilencePy3Deprecations):
 
     def _getTargetClass(self):
         from zope.interface.registry import UtilityRegistration
@@ -1940,7 +1945,7 @@
 
     def _makeOne(self, component=None, factory=None):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -2001,7 +2006,7 @@
     def test___hash__(self):
         _component = object()
         ur, _registry, _name = self._makeOne(_component)
-        self.assertEqual(hash(ur), id(ur))
+        self.assertEqual(ur.__hash__(), id(ur))
 
     def test___eq___identity(self):
         _component = object()
@@ -2117,7 +2122,7 @@
         self.failUnless(ur2 >= ur)
 
 
-class AdapterRegistrationTests(unittest.TestCase):
+class AdapterRegistrationTests(_SilencePy3Deprecations):
 
     def _getTargetClass(self):
         from zope.interface.registry import AdapterRegistration
@@ -2125,7 +2130,7 @@
 
     def _makeOne(self, component=None):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -2187,7 +2192,7 @@
     def test___hash__(self):
         _component = object()
         ar, _registry, _name = self._makeOne(_component)
-        self.assertEqual(hash(ar), id(ar))
+        self.assertEqual(ar.__hash__(), id(ar))
 
     def test___eq___identity(self):
         _component = object()
@@ -2334,7 +2339,7 @@
 
     def _makeOne(self, component=None):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')
@@ -2363,7 +2368,7 @@
         verifyObject(ISubscriptionAdapterRegistration, sar)
 
 
-class HandlerRegistrationTests(unittest.TestCase):
+class HandlerRegistrationTests(_SilencePy3Deprecations):
 
     def _getTargetClass(self):
         from zope.interface.registry import HandlerRegistration
@@ -2371,7 +2376,7 @@
 
     def _makeOne(self, component=None):
         from zope.interface.declarations import InterfaceClass
-        from zope.interface.registry import _u
+        from zope.interface._compat import _u
         class IFoo(InterfaceClass):
             pass
         ifoo = IFoo('IFoo')

Modified: zope.interface/trunk/src/zope/interface/tests/test_verify.py
===================================================================
--- zope.interface/trunk/src/zope/interface/tests/test_verify.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/tests/test_verify.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -50,27 +50,28 @@
 
     def test_class_doesnt_have_required_method_simple(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenImplementation
 
         class ICurrent(Interface):
             def method(): pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
+            pass
 
         self.assertRaises(BrokenImplementation,
                           self._callFUT, ICurrent, Current)
 
     def test_class_has_required_method_simple(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
             def method(): pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self):
                 pass
@@ -79,7 +80,7 @@
 
     def test_class_doesnt_have_required_method_derived(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenImplementation
 
         class IBase(Interface):
@@ -89,15 +90,16 @@
         class IDerived(IBase):
             pass
 
+        @implementer(IDerived)
         class Current(object):
-            implements(IDerived)
+            pass
 
         self.assertRaises(BrokenImplementation,
                           self._callFUT, IDerived, Current)
 
     def test_class_has_required_method_derived(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class IBase(Interface):
             def method():
@@ -106,8 +108,8 @@
         class IDerived(IBase):
             pass
 
+        @implementer(IDerived)
         class Current(object):
-            implements(IDerived)
 
             def method(self):
                 pass
@@ -117,15 +119,15 @@
     def test_method_takes_wrong_arg_names_but_OK(self):
         # We no longer require names to match.
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, b):
                 pass
@@ -134,7 +136,7 @@
 
     def test_method_takes_not_enough_args(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -142,8 +144,8 @@
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self):
                 pass
@@ -153,7 +155,7 @@
 
     def test_method_doesnt_take_required_starargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -161,8 +163,8 @@
             def method(*args):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self):
                 pass
@@ -172,7 +174,7 @@
 
     def test_method_doesnt_take_required_only_kwargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -180,8 +182,8 @@
             def method(**kw):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self):
                 pass
@@ -191,7 +193,7 @@
 
     def test_method_takes_extra_arg(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -199,8 +201,8 @@
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a, b):
                 pass
@@ -210,15 +212,15 @@
 
     def test_method_takes_extra_arg_with_default(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a, b=None):
                 pass
@@ -227,15 +229,15 @@
 
     def test_method_takes_only_positional_args(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, *args):
                 pass
@@ -244,7 +246,7 @@
 
     def test_method_takes_only_kwargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -252,8 +254,8 @@
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, **kw):
                 pass
@@ -263,15 +265,15 @@
 
     def test_method_takes_extra_starargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a, *args):
                 pass
@@ -280,15 +282,15 @@
 
     def test_method_takes_extra_starargs_and_kwargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(a):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a, *args, **kw):
                 pass
@@ -297,7 +299,7 @@
 
     def test_method_doesnt_take_required_positional_and_starargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -305,8 +307,8 @@
             def method(a, *args):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a):
                 pass
@@ -316,15 +318,15 @@
 
     def test_method_takes_required_positional_and_starargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(a, *args):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a, *args):
                 pass
@@ -333,15 +335,15 @@
 
     def test_method_takes_only_starargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(a, *args):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, *args):
                 pass
@@ -350,15 +352,15 @@
 
     def test_method_takes_required_kwargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
 
             def method(**kwargs):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, **kw):
                 pass
@@ -367,7 +369,7 @@
 
     def test_method_takes_positional_plus_required_starargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -375,8 +377,8 @@
             def method(*args):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a, *args):
                 pass
@@ -387,7 +389,7 @@
 
     def test_method_doesnt_take_required_kwargs(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
@@ -395,8 +397,8 @@
             def method(**kwargs):
                 pass
 
+        @implementer(ICurrent)
         class Current(object):
-            implements(ICurrent)
 
             def method(self, a):
                 pass
@@ -408,13 +410,13 @@
     def test_class_has_method_for_iface_attr(self):
         from zope.interface import Attribute
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
             attr = Attribute("The foo Attribute")
 
+        @implementer(ICurrent)
         class Current:
-            implements(ICurrent)
 
             def attr(self):
                 pass
@@ -423,15 +425,15 @@
 
     def test_class_has_nonmethod_for_method(self):
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenMethodImplementation
 
         class ICurrent(Interface):
             def method():
                 pass
 
+        @implementer(ICurrent)
         class Current:
-            implements(ICurrent)
             method = 1
 
         self.assertRaises(BrokenMethodImplementation,
@@ -440,13 +442,13 @@
     def test_class_has_attribute_for_attribute(self):
         from zope.interface import Attribute
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
             attr = Attribute("The foo Attribute")
 
+        @implementer(ICurrent)
         class Current:
-            implements(ICurrent)
 
             attr = 1
 
@@ -456,20 +458,21 @@
         # This check *passes* for verifyClass
         from zope.interface import Attribute
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class ICurrent(Interface):
             attr = Attribute("The foo Attribute")
 
+        @implementer(ICurrent)
         class Current:
-            implements(ICurrent)
+            pass
 
         self._callFUT(ICurrent, Current)
 
     def test_w_callable_non_func_method(self):
         from zope.interface.interface import Method
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
 
         class QuasiMethod(Method):
             def __call__(self, *args, **kw):
@@ -482,8 +485,8 @@
         class ICurrent(Interface):
             attr = QuasiMethod('This is callable')
 
+        @implementer(ICurrent)
         class Current:
-            implements(ICurrent)
             attr = QuasiCallable()
 
         self._callFUT(ICurrent, Current)
@@ -500,14 +503,15 @@
         # This check *fails* for verifyObject
         from zope.interface import Attribute
         from zope.interface import Interface
-        from zope.interface import implements
+        from zope.interface import implementer
         from zope.interface.exceptions import BrokenImplementation
 
         class ICurrent(Interface):
             attr = Attribute("The foo Attribute")
 
+        @implementer(ICurrent)
         class Current:
-            implements(ICurrent)
+            pass
 
         self.assertRaises(BrokenImplementation,
                           self._callFUT, ICurrent, Current)

Modified: zope.interface/trunk/src/zope/interface/verify.py
===================================================================
--- zope.interface/trunk/src/zope/interface/verify.py	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/src/zope/interface/verify.py	2012-04-17 15:31:46 UTC (rev 125152)
@@ -74,7 +74,7 @@
                 # Nope, just a normal function
                 meth = fromFunction(attr, iface, name=name)
         elif (isinstance(attr, MethodTypes)
-              and type(attr.im_func) is FunctionType):
+              and type(attr.__func__) is FunctionType):
             meth = fromMethod(attr, iface, name)
         else:
             if not callable(attr):

Modified: zope.interface/trunk/tox.ini
===================================================================
--- zope.interface/trunk/tox.ini	2012-04-17 15:30:54 UTC (rev 125151)
+++ zope.interface/trunk/tox.ini	2012-04-17 15:31:46 UTC (rev 125152)
@@ -16,7 +16,6 @@
 
 [testenv:py32]
 deps = zope.event
-       zope.fixers
 
 [testenv:coverage]
 basepython =



More information about the checkins mailing list