Therefore, naively, assuming the _select hack was the best we could do, until the Storm bug is fixed I think we need to sniff for sqlobject. Something on the order of the following might work.
# XXX The following code hacks around Storm bug 620508.
resultset = removeSecurityProxy(self.context)
if isinstance(resultset, storm.sqlobject.SQLObjectResultSet):
# It is particularly annoying to handle the Storm bug here
# because it requires fixing up a wrapped object.
if zope.proxy.queryProxy(self.context, zope.security.proxy.Proxy):
# This is a security-proxied object.
# We need to manually check whether it is OK to access count,
# because we are going to bypass the whole shebang.
checker = zope.security.checker.getChecker(self.context)
# This will raise the appropriate error if the checker would not
# have allowed access. checker.checker.check_getattr(self.context, 'count')
context = resultset._without_prejoins() # This is not proxied.
resultset = context
else:
context = self.context # This is proxied.
if getattr(resultset, '_select', None) is None: # hasattr swallows exceptions.
resultset._select.limit = Undef
resultset._select.offset = Undef
return context.count()
Now the questions are, (a) does anyone agree with me, and (b) how do we test this?
The sqlobject code that failed was in this method:
def count(self): prejoins( )._result_ set
result_set = self._without_
return result_set.count()
The fix for non-sqlobject storm was in lib/canonical/ launchpad/ webapp/ batching. py :
49 resultset = removeSecurityP roxy(self. context) _select. limit = Undef _select. offset = Undef count()
50 if hasattr(resultset, '_select'):
51 resultset.
52 resultset.
53 return self.context.
Therefore, naively, assuming the _select hack was the best we could do, until the Storm bug is fixed I think we need to sniff for sqlobject. Something on the order of the following might work.
# XXX The following code hacks around Storm bug 620508. roxy(self. context) resultset, storm.sqlobject .SQLObjectResul tSet): queryProxy( self.context, zope.security. proxy.Proxy) : checker. getChecker( self.context)
checker. checker. check_getattr( self.context, 'count') _without_ prejoins( ) # This is not proxied. _select. limit = Undef _select. offset = Undef
resultset = removeSecurityP
if isinstance(
# It is particularly annoying to handle the Storm bug here
# because it requires fixing up a wrapped object.
if zope.proxy.
# This is a security-proxied object.
# We need to manually check whether it is OK to access count,
# because we are going to bypass the whole shebang.
checker = zope.security.
# This will raise the appropriate error if the checker would not
# have allowed access.
context = resultset.
resultset = context
else:
context = self.context # This is proxied.
if getattr(resultset, '_select', None) is None: # hasattr swallows exceptions.
resultset.
resultset.
return context.count()
Now the questions are, (a) does anyone agree with me, and (b) how do we test this?