[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