[Zope-Checkins] SVN: Zope/branches/2.13/ fix `LazyMap` to avoid unnecessary function calls when not accessing items in order (fixes http://dev.plone.org/plone/ticket/9018)
Andreas Zeidler
az at zitc.de
Tue Dec 14 09:12:11 EST 2010
Log message for revision 118863:
fix `LazyMap` to avoid unnecessary function calls when not accessing items in order (fixes http://dev.plone.org/plone/ticket/9018)
Changed:
U Zope/branches/2.13/doc/CHANGES.rst
U Zope/branches/2.13/src/Products/ZCatalog/Lazy.py
U Zope/branches/2.13/src/Products/ZCatalog/tests/test_lazy.py
-=-
Modified: Zope/branches/2.13/doc/CHANGES.rst
===================================================================
--- Zope/branches/2.13/doc/CHANGES.rst 2010-12-14 13:24:24 UTC (rev 118862)
+++ Zope/branches/2.13/doc/CHANGES.rst 2010-12-14 14:12:11 UTC (rev 118863)
@@ -11,6 +11,8 @@
Bugs Fixed
++++++++++
+- Fix `LazyMap` to avoid unnecessary function calls.
+
- LP 686664: WebDAV Lock Manager ZMI view wasn't accessible.
2.13.1 (2010-12-07)
Modified: Zope/branches/2.13/src/Products/ZCatalog/Lazy.py
===================================================================
--- Zope/branches/2.13/src/Products/ZCatalog/Lazy.py 2010-12-14 13:24:24 UTC (rev 118862)
+++ Zope/branches/2.13/src/Products/ZCatalog/Lazy.py 2010-12-14 14:12:11 UTC (rev 118863)
@@ -145,44 +145,28 @@
# Don't access data until necessary
def __init__(self, func, seq, length=None):
- self._seq = seq
- self._data = []
- self._func = func
+ self._seq=seq
+ self._func=func
if length is not None:
- self._len = length
+ self._len=length
else:
self._len = len(seq)
+ self._marker = object()
+ self._data = [self._marker] * self._len
- def __getitem__(self, index):
- data = self._data
+ def __getitem__(self,index):
+ data=self._data
try:
- s = self._seq
+ s=self._seq
except AttributeError:
return data[index]
- i = index
- if i < 0:
- i = len(self) + i
- if i < 0:
- raise IndexError(index)
+ value = data[index]
+ if value is self._marker:
+ value = data[index] = self._func(s[index])
+ return value
- ind = len(data)
- if i < ind:
- return data[i]
- ind = ind - 1
- func = self._func
- while i > ind:
- try:
- ind = ind + 1
- data.append(func(s[ind]))
- except IndexError:
- del self._func
- del self._seq
- raise IndexError(index)
- return data[i]
-
-
class LazyFilter(Lazy):
# Act like a sequence, but get data from a filtering process.
# Don't access data until necessary. Only data for which test(data)
Modified: Zope/branches/2.13/src/Products/ZCatalog/tests/test_lazy.py
===================================================================
--- Zope/branches/2.13/src/Products/ZCatalog/tests/test_lazy.py 2010-12-14 13:24:24 UTC (rev 118862)
+++ Zope/branches/2.13/src/Products/ZCatalog/tests/test_lazy.py 2010-12-14 14:12:11 UTC (rev 118863)
@@ -113,7 +113,17 @@
lmap = self._createLMap(filter, seq1, seq2, seq3)
self._compare(lmap, [str(x).lower() for x in (seq1 + seq2 + seq3)])
+ def testMapFuncIsOnlyCalledAsNecessary(self):
+ seq = range(10)
+ count = [0] # closure only works with list, and `nonlocal` in py3
+ def func(x):
+ count[0] += 1
+ return x
+ lmap = self._createLMap(func, seq)
+ self.assertEqual(lmap[5], 5)
+ self.assertEqual(count[0], 1)
+
class TestLazyFilter(TestLazyCat):
def _createLSeq(self, *seq):
More information about the Zope-Checkins
mailing list