[Zope-CMF] Odd behavior with lazy ActionInfo evaluation in CMF 1.5

Alec Mitchell apm13 at columbia.edu
Thu Jun 30 12:11:32 EDT 2005


Hello all,

I've noticed something odd when viewing the Plone 2.1 (CMF-1.5 branch) 
front-page as Anonymous.  The 'user' action 'join' defined in 
portal_registration gives as it's url 'http://mysite/test_site/join_form', as 
expected.  The same action when retrieved again in 'portlet_login' gives 
'http://mysite/test_site/<function _getURL at 0x40fa102c>', which is 
obviously a problem.

I've done a little hand debugging to attempt to figure out how this happens, 
and have found the following:

1) On page view, 'global_defines.pt' is called from main_template and defines 
the 'action' structure using a call to 
portal_actions.listFilteredActionsFor(here).
2) This creates the lazily mapped ActionInfo object for the 'join' action from 
the 'join' ActionInformation object in portal_registration.  At this time 
actions['join']['url'] is set to self._getURL, and the key 'url' is added to 
the ActionInfo's 'lazy_keys' list.
3) This ActionInfo object, unchanged, is used in the path expression 
'action/url' in the loop through user actions in 'global_personalbar.pt' 
which is called from main_template.
4) This causes ActionInfo.__getitem__ to be called for 'url' and the _getURL 
method is retrieved.  Because 'url' is in 'lazy_keys', the method is 
evaluated, the the ActionInfo dict is updated with the evaluated value for 
'url', and the 'url' entry is removed from 'lazy_keys'.

The above steps are the expected behavior, and appear to work perfectly.  The 
strange part follows:

5) 'portlet_login' gets the url for the action using "[a['url'] for a in 
actions['user'] if a['id']=='join']".
6) This results in another call to ActionInfo.__getitem__ on what should be 
the same ActionInfo instance.  Again the _getURL method is retrieved, which 
is unexpected as that value was replaced with the result of calling the 
method in step #4 above.  'lazy_keys' no longer has the entry 'url', so the 
method is not evaluated, and the method itself is returned.

Though the ActionInfo for this action is only created once, and the changes 
made to it's 'lazy_keys' variable can be seen on subsequent calls to the 
instance, it appears that some of the changes to the object are getting lost 
between subsequent calls to __getitem__.  In fact, I tested setting a new 
instance variable during the __getitem__ call, and on the subsequent call 
this variable was no longer set!

If these were persistent objects I would attribute this sort of weirdness to 
the need for some _p_changed updates or some partial transaction rollback, 
but these are simple UserDict subclasses which are never stored in the ZODB.  
I've thus far been unable to write a unit test which demonstrates the bug, 
but it is easily repeatable.  Anybody have an idea what might be going on 
here?

Alec


More information about the Zope-CMF mailing list