RE: [Zope-dev] Re: Better encapsulation is good...
Did you run the Article class through Globals.default__class_init__()? E.g. (at the module level), e.g.:
Globals.default__class_init__(Article)
Yes, I tried this too, (saw it in the mailing list archive).
(I'm coming to this late, so ignore me if this is covered ground...) Are you certain that you are not losing the acquistion context on your Articles somehow? For example, if you are not doing a getattr on the container to get an article, you may need to maintain the acquistion chain yourself: class Article(Acquistion.Implicit): ... class Articles: """The container for articles. Note that I dont really contain them though - I get them from a database or something (or create them on the fly)""" def getArticle(self, id): # we create an Article on the fly, so we have to # "wrap" the object in the context of its container # to preserve the acquisition chain (and security # depends on an intact acquisition chain) item=Article(id) # this is the wrapping! return item.__of__(self) Hope this helps... Brian Lloyd brian@digicool.com Software Engineer 540.371.6909 Digital Creations http://www.digicool.com
Brian Lloyd wrote:
(I'm coming to this late, so ignore me if this is covered ground...)
It isn't :S
Are you certain that you are not losing the acquistion context on your Articles somehow?
There's a good chance that's right :S Is there anything bad about storing wrapped attributes in a persistent object? Butch seemed pretty religious about unwrapping objects before he stored them, and maybe he ain't quite wrapping them up right on the way out... This may be a stupid question, but why does the object need to be wrapped for security to work anyway? cheers, Chris
Brian, Shane and anyone else who's interested... Help! I'm dying here ;-) (and yes, I know it's a Friday) Chris Withers wrote:
Are you certain that you are not losing the acquistion context on your Articles somehow?
Well, okay, I don't think so... here's the source causing the problem: <dtml-if site_item_list> <dtml-in site_item_list> <dtml-if "subject_image(subject)">woohoo!</dtml-if> </dtml-in site_item_list> </dtml-if site_item_list> And here's the traceback with my (hopefully helpful ;-) comments:
Traceback (innermost last): File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 222, in publish_module File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 187, in publish File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 171, in publish File E:\Zope\227194~1.0\lib\python\ZPublisher\mapply.py, line 160, in mapply (Object: index_html)
index_html is a DTML method, than contains <dtml-var site_header>. It lives in the Squishdot Site object, which also contains the articles and other stuff. If you want real details, see Squishdot.py in Squishdot 0.7.0...
File E:\Zope\227194~1.0\lib\python\ZPublisher\Publish.py, line 112, in call_object (Object: index_html) File E:\Zope\227194~1.0\lib\python\OFS\DTMLMethod.py, line 167, in __call__ (Object: index_html) File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_String.py, line 502, in __call__ (Object: index_html) File E:\Zope\227194~1.0\lib\python\OFS\DTMLMethod.py, line 163, in __call__ (Object: site_header)
So here's site_header, also a DTML method...
File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_String.py, line 502, in __call__ (Object: site_header) File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_In.py, line 691, in renderwob (Object: site_item_list)
I presume this means we're inside the the <dtml-in> now? What would the <dtml-if> show in this traceback? (if anything...)
File E:\Zope\227194~1.0\lib\python\DocumentTemplate\DT_Util.py, line 331, in eval (Object: subject_image(subject)) (Info: subject)
Okay, so here's the source of the problem... I guess this 'subejct' comes from the namespace provided by the <dtml-in> over site_item_list... sound about right? ('subject' can't be acquired from the containing SquishSite object, SquishSite's don't have an attribute with that name ;-). Right, here's site_item_list: # protected by 'View' permission def site_item_list(self): # """ returns latest articles from today """ currtime = int(time()) return map(lambda x, p=self: x.__of__(p), self.data.map(self.site_id_list(currtime))) ^^^^^^^^^^^ So it looks like at least an attempt at wrapping has been done... See the PPS for the explanation of what site_id_list does :S (short version: returns a list of article ids (integers), lots of contortions about which ids are picked :S) Which raises the question of what self.data.map does... Okay self.data is an IOBTree containing all the articles in the site (unwrapped, I think) So I'm guessing data.map takes a list of integers and returns the appropriate article objects. Funky, Shane, I know both you and I have wondered what that did ;-) Anyway, taking that in mind, it would suggest the article objects being returned are wrapped in the context of self, which is the Squishdot Site object, which is just a 'normal' Acquisition.Implicit Zope object. So, I don't think it's acquisition wrapping or lack of it which is the problem, unless anyone can tell me better...
File E:\Zope\227194~1.0\lib\python\OFS\DTMLMethod.py, line 189, in validate (Object: index_html) File E:\Zope\227194~1.0\lib\python\AccessControl\SecurityManager.py, line 139, in validate File E:\Zope\227194~1.0\lib\python\AccessControl\ZopeSecurityPolicy.py, line 159, in validate Unauthorized: subject
So anyway, subject is a string attribute of the (wrapped) article objects being returned by site_item_list(). I guess how it's being got is through an InstanceDict for the Article being plopped on the namespace stack and 'subject' being used as a key to this dictionary. Can anyone think of any nastiness happening here? If not, I'm at a loss :( I really hope someone can help/explain further, cheers, Chris PS: What does the following mean? (seen a lot when editing and browsing stuff in Zope through FTP) 2000-09-01T14:55:20 PROBLEM(100) ZServer unhandled connect event PPS: site_id_list__roles__=[] def site_id_list(self, currtime): # """ returns latest id list from currtime """ ilist = self.id_list(currtime) tdict = {} tlist = [] ilen = len(ilist) cnt = 0 while (cnt < ilen) and (len(tdict) < 5): id = ilist[cnt] item = self.data[id] if tdict.has_key(item.subject): pass else: tdict[item.subject] = id tlist.append(id) cnt = cnt + 1 return tlist so, we need id_list: id_list__roles__=[] def id_list(self, currtime): # ''' returns id list of latest articles at currtime ''' rlist = self.rev_id_list() max = self.max_itemlist min = max / 3 rlen = len(rlist) if rlen <= min: pass # take all elements else: today_list = self.date_id_list(currtime) # take only items from today tlen = len(today_list) if tlen <= min: rlist = rlist[:min] # take minimum elements even though some items came from yesterday else: if tlen >= max: rlist = today_list[:max] # take maximum elements from today else: rlist = today_list # take entire list of items from today return rlist great, so now we need rev_id_list :S : rev_id_list__roles__=[] def rev_id_list(self): # """ returns reversed id list of reviewed articles """ rlist = map(None,self.ids) rlist = filter(lambda x,p=self : p.data[x].reviewed, rlist) rlist.reverse() return rlist I'm 90% sure self.ids is an intSet containing the ids of the postings attached to the current posting (or the SquishSite in this case...) self.data is covered above already...
participants (2)
-
Brian Lloyd -
Chris Withers