implementedBy() is broken in Python 3.2

Bug #911851 reported by Barry Warsaw
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
zope.interface
Won't Fix
Undecided
Unassigned

Bug Description

While porting some existing code using zope.interface to Python 3.2, I noticed that Interface.implementedBy() appears to be broken in Python 3.2. This sample code prints True in Python 2.7 in a virtualenv with zope.interface-3.8.0, but False in a Python 3.2 virtualenv.

from __future__ import print_function
__metaclass__ = type

from zope.interface import Interface, implements

class MyInterface(Interface):
    pass

class MyClass:
    implements(MyInterface)

print(MyInterface.implementedBy(MyClass))

I think the reason is that MyClass doesn't end up with an __implements__ attribute, but I'm not sure why that is.

Revision history for this message
Tres Seaver (tseaver) wrote :

This is a know problem with the "class advice" mechanism used for
'implements', 'implementsOnly', and 'classProvides': they abuse the stack
frame to mutate the locals of their suite in a way which doesn't work in Py3k.
The (portable) workaround is to use the 'implementer' ('implementor_only' /
'provider') class decorators::

  from zope.interface import implementer

  @implementer(MyInterface)
  class MyClass(object):
      pass

"Portable" obviously only includes Py2 versions which support class
decorators (>= 2.6).

Changed in zope.interface:
status: New → Won't Fix
Revision history for this message
Barry Warsaw (barry) wrote : Re: [Bug 911851] Re: implementedBy() is broken in Python 3.2

On Jan 04, 2012, at 05:53 PM, Tres Seaver wrote:

>This is a know problem with the "class advice" mechanism used for
>'implements', 'implementsOnly', and 'classProvides': they abuse the stack
>frame to mutate the locals of their suite in a way which doesn't work in Py3k.
>The (portable) workaround is to use the 'implementer' ('implementor_only' /
>'provider') class decorators::
>
> from zope.interface import implementer
>
> @implementer(MyInterface)
> class MyClass(object):
> pass
>
>"Portable" obviously only includes Py2 versions which support class
>decorators (>= 2.6).

Cool, I didn't even know about @implementer. That syntax isn't too bad
either, and I think it might even be an improvement over the implements()
syntax (though it takes a little getting used to).

I only care about Python >= 2.6 so that's fine.

Thanks! I'm going to add this to my followup post about porting to Python 3.

Revision history for this message
Jim Fulton (jim-zope) wrote :

We should cause the old syntax to fail more clearly in py3k and maybe warn in Python 2.7. I'll create a separate issue.

Revision history for this message
Barry Warsaw (barry) wrote :

On Jan 04, 2012, at 09:17 PM, Jim Fulton wrote:

>We should cause the old syntax to fail more clearly in py3k and maybe
>warn in Python 2.7. I'll create a separate issue.

+1. As it stands, the failure is completely silent.

Please subscribe me to the new issue.

Revision history for this message
Marius Gedminas (mgedmin) wrote :

For the record: the new issue is bug 911995.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.