[Zope] Re: Five: Adapter registry not working?

Peter Sabaini peter at sabaini.at
Mon Jun 4 10:21:44 EDT 2007


FTR: I tracked this down again some more -- the culprit is not the adapter 
registry but a failing getUtility() call.

I really wish component lookup / adapation would be easier to debug; IMHO this 
is pretty opaque -- but then again I'm a newb at this.

peter.



On Wednesday 30 May 2007 18:51:18 Peter Sabaini wrote:
> On Wed 2007-05-30 17:14:13 Tres Seaver wrote:
> > Peter Sabaini wrote:
> > > Hi list,
> > >
> > > I am clearly doing something wrong here.
> > >
> > > I try to use an Adapter from zope.app.session with an HTTPRequest
> > > object, but the Adapterregistry doesnt quite cooperate.
> > >
> > > Specifically, I try to adapt a HTTPRequest object to
> > > zope.app.session.interfaces.IClientId via the Adapter
> > > zope.app.session.session.ClientId
> > >
> > > A short demo:
> > >
> > >     % ./zopectl debug
> > >      [ ... ]
> > >
> > > Import stuff:
> > >     >>> from ZPublisher.HTTPRequest import *
> > >     >>> from StringIO import StringIO
> > >     >>> from zope.app.session.session import ClientId
> > >     >>> from zope.app.session.interfaces import IClientId
> > >     >>> from zope import component
> > >     >>> from zope.interface import *
> > >
> > > Create ourselves a faux request object:
> > >     >>> env = {'SERVER_NAME': '', 'SERVER_PORT' : ''}
> > >     >>> request = HTTPRequest(StringIO(), env, None)
> > >
> > > ClientId implements IClientId:
> > >     >>> list(implementedBy(ClientId))
> > >
> > >     [<InterfaceClass zope.app.session.interfaces.IClientId>]
> > >
> > > It seems ClientId is an Adapter for IRequest:
> > >     >>> component.adaptedBy(ClientId)
> > >
> > >     (<InterfaceClass zope.publisher.interfaces.IRequest>,)
> > >
> > > request implements IBrowserRequest, which is a subclass of IRequest:
> > >     >>> list(providedBy(request))
> > >
> > >     [<InterfaceClass
> > > zope.publisher.interfaces.browser.IBrowserRequest>]
> > >
> > >     >>> issubclass(list(providedBy(request))[0],
> > >     >>> component.adaptedBy(ClientId)
> > >
> > > [0])
> > >     True
> > >
> > > ...so I'd expect to get ClientId as an Adapter for IClientId(request),
> > > but I
> > >
> > > dont:
> > >     >>> IClientId(request)
> > >
> > >     Traceback (most recent call last):
> > >       File "<stdin>", line 1, in ?
> > >     TypeError: ('Could not adapt', <HTTPRequest, URL=http://:>,
> > > <InterfaceClass zope.app.session.interfaces.IClientId>)
> > >
> > >
> > > Shouldnt this work? Obviously I am missing something here.
> > > This is on Zope 2.10.2 with the built-in Five, and Python 2.4.4
> > >
> > > Any help greatly appreciated!
> >
> > You have verified that 'ClientID' is a suitable candidate for adapting
> > 'IRequest' to 'IClientID', but not that it has been actually registered
> > as the factory for that adaptaion.
>
> Ah, I see. I thought component.adaptedBy() checked the actual
> registration...
>
> > Does adding the following help?
> >
> >   >>> from zope.component import provideAdapter
> >   >>> provideAdapter(ClientID)
>
> Nope, I still get the "Could not adapt ... " error.
>
> Besides, zope/app/session/configure.zcml has the following:
>
>   <adapter
>       factory=".session.ClientId"
>       permission="zope.Public"
>       />
>
> and ClientId has:
>
>     class ClientId(str):
>         implements(IClientId)
>         adapts(IRequest)
>
> Does that take care of registration?
>
> I wonder if I need to do some special Five incantation to make the global
> registration work?
>
> This, on the other hand, works quite well (lifted from some unit tests):
>     >>> from cStringIO import StringIO
>     >>> from zope.app.testing import ztapi, placelesssetup
>     >>> from zope.app.session.interfaces import IClientId, IClientIdManager
>     >>> from zope.app.session.session import ClientId
>     >>> from zope.app.session.http import CookieClientIdManager
>     >>> from zope.publisher.interfaces import IRequest
>     >>> from zope.publisher.http import HTTPRequest
>     >>>
>     >>> placelesssetup.setUp()
>     >>> ztapi.provideAdapter(IRequest, IClientId, ClientId)
>     >>> ztapi.provideUtility(IClientIdManager, CookieClientIdManager())
>     >>> request = HTTPRequest(StringIO(), {}, None)
>     >>> IClientId(request)
>
>     'WiKfis240zXEVZ0UWM6H6AsWc6kYwJyviHNXhGqd835xsnZhKlzfjc'
>
> The difference: zope.publisher.http.HTTPRequest is a new-style class (is
> that required?), and placelesssetup.setUp() is executed (what does it do?)
>
> > Also, at the point where the lookup fails, you can try:
> >   >>> import pdb; pdb.pm()
> >
> > and be in a "postmortem" traceback of the failed component tookup.
>
> I'm afraid I'm not sure what I should be looking for...
>
> Thanks a lot,
> peter.
>
> > Tres.
>
> _______________________________________________
> Zope maillist  -  Zope at zope.org
> http://mail.zope.org/mailman/listinfo/zope
> **   No cross posts or HTML encoding!  **
> (Related lists -
>  http://mail.zope.org/mailman/listinfo/zope-announce
>  http://mail.zope.org/mailman/listinfo/zope-dev )




More information about the Zope mailing list