zope.interface: adapter for ClassType doesn't work right

Bug #98380 reported by James Y Knight
6
Affects Status Importance Assigned to Milestone
Twisted
New
Unknown
Zope 3
Won't Fix
Medium
Lennart Regebro
3.2
Won't Fix
Undecided
Unassigned
3.3
Won't Fix
Undecided
Unassigned
3.4
Won't Fix
Medium
Lennart Regebro
zope.interface
Won't Fix
Medium
Lennart Regebro

Bug Description

The following example program shows that registering an adapter for ClassType doesn't work as it should, until after calling "declarations.implementedBy(Bar)", which should be a purely lookup function and not change anything. I'm not really sure if there's actually has a real use case for doing this or not but it does look like a bug.

Forwarded from: http://twistedmatrix.com/trac/ticket/634

 from zope.interface import Interface, declarations, adapter
 import types

 class IFoo(Interface): pass

 class Bar: pass

 class Baz: pass

 def f1(obj): pass

 def f2(obj): pass

 ar=adapter.AdapterRegistry()
 ar.register([declarations.implementedBy(types.ClassType)], IFoo, '', f1)
 ar.lookup1(declarations.providedBy(Bar), IFoo)
 # result is None, expected f1

 declarations.implementedBy(Bar)
 ar.lookup1(declarations.providedBy(Bar), IFoo)
 # Result is f1

Revision history for this message
Christian Theune (ctheune) wrote :

The behaviour described is still there. I don't know whether this is intended or not. It looks like it *might* not be intended.

Changed in zope3:
status: New → Confirmed
Revision history for this message
Stephan Richter (srichter) wrote :

I think that we do not support classic classes or are we?

Revision history for this message
ChrisW (chris-simplistix) wrote : Re: [Bug 98380] Re: zope.interface: adapter for ClassType doesn't work right

It would be a bit disappointing if we didn't support classic classes...

zope.interface is one of the few packages to be used widely outside of
zope and I'm sure some of the downstream users would still like to be
using classic classes...

Chris

--
Simplistix - Content Management, Zope & Python Consulting
            - http://www.simplistix.co.uk

Revision history for this message
James Y Knight (foom) wrote :

...Of course, this bug was first reported in 2004, and apparently hasn't bothered anyone else since then.

And ClassType is, itself, an ahem "newstyle class".

But truly, registering adapters against the class "ClassType" itself is exceedingly rare; if this is some terrible implementation detail preventing it from working without unreasonable tricks, it wouldn't bother me to see it just be a documented limitation.

Revision history for this message
Jean-Paul Calderone (exarkun) wrote :

Almost a year later... It'd be good to know if this is going to be fixed (when someone gets the time), or if it's a limitation of zope.interface that we should live with.

Changed in twisted:
status: Unknown → New
Revision history for this message
Glyph Lefkowitz (glyph) wrote :

Here's a patch expressing the above example as a failing doctest. Not the best place for me to have put this, I'm sure, but here it is:

Index: src/zope/interface/adapter.txt
===================================================================
--- src/zope/interface/adapter.txt (revision 98734)
+++ src/zope/interface/adapter.txt (working copy)
@@ -544,3 +544,33 @@
   >>> registry.subscribe([IR1], None, handler)
   >>> registry.subscriptions([IR1], None) == [handler]
   True
+
+
+Bugs
+----
+
+I don't know where to put this, so here you go.
+
+ >>> from zope.interface import Interface, declarations, adapter
+ >>> import types
+ >>> class IFoo(Interface): pass
+ ...
+ >>> class Bar: pass
+ ...
+ >>> class Baz: pass
+ ...
+ >>> def f1(obj): pass
+ ...
+ >>> def f2(obj): pass
+ ...
+ >>> ar = adapter.AdapterRegistry()
+ >>> ar.register([declarations.implementedBy(types.ClassType)], IFoo, '', f1)
+ >>> ar.lookup1(declarations.providedBy(Bar), IFoo) #doctest: +ELLIPSIS
+ <function f1 at ...>
+ >>> declarations.implementedBy(Bar)
+ <implementedBy __main__.Bar>
+ >>> ar.lookup1(declarations.providedBy(Bar), IFoo) #doctest: +ELLIPSIS
+ <function f1 at ...>
+ >>> # Result is f1
+ ...
+

Revision history for this message
Lennart Regebro (regebro-gmail) wrote :

A bit more information:

providedBy will first look for a __providedBy__ attribute. ClassType doesn't have that, so it will then return getObjectSpecification(ob), which in turn returns <zope.interface.declarations.Declaration object ...>

implementedBy will look for an __implements__. If none is provided, it will figure out what the class implements, and set that as __implements__, and also set __providedBy__ to objectSpecificationDescriptor. The next providedBy will now return a <zope.interface.declarations.ClassProvides object ...> instead.

I don't know what The Right Thing is here, but this is only a problem if you want to create an adapter for all classic classes, but not new classes. Which is a rather strange usecase, and is probably the reason why few people encountered this bug.

Tres Seaver (tseaver)
Changed in zope.interface:
assignee: nobody → Lennart Regebro (regebro-gmail)
importance: Undecided → Medium
status: New → Confirmed
Tres Seaver (tseaver)
Changed in zope3:
status: Confirmed → Won't Fix
Revision history for this message
Jean-Paul Calderone (exarkun) wrote :

Thanks!

Tres Seaver (tseaver)
tags: added: bugday20100424
Tres Seaver (tseaver)
Changed in zope.interface:
status: Confirmed → Won't Fix
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.