[Checkins] SVN: zc.sourcefactory/trunk/src/zc/sourcefactory/ calling bool() (or the equivalent) on a source who's items are numerous or

Benji York benji at zope.com
Tue Feb 12 22:44:41 EST 2008


Log message for revision 83773:
  calling bool() (or the equivalent) on a source who's items are numerous or
  expensive to materialize was unnecessarily expensive (__len__ was called
  because there was no __nonzero__ method), fixed with a test
  

Changed:
  U   zc.sourcefactory/trunk/src/zc/sourcefactory/README.txt
  U   zc.sourcefactory/trunk/src/zc/sourcefactory/source.py

-=-
Modified: zc.sourcefactory/trunk/src/zc/sourcefactory/README.txt
===================================================================
--- zc.sourcefactory/trunk/src/zc/sourcefactory/README.txt	2008-02-13 00:34:04 UTC (rev 83772)
+++ zc.sourcefactory/trunk/src/zc/sourcefactory/README.txt	2008-02-13 03:44:40 UTC (rev 83773)
@@ -14,6 +14,7 @@
 allow users to define only the business relevant code for getting a list of
 values, getting a token and a title to display.
 
+
 Simple case
 -----------
 
@@ -41,6 +42,7 @@
   >>> len(source)
   3
 
+
 Contextual sources
 ------------------
 
@@ -84,6 +86,7 @@
   >>> len(source)
   4
 
+
 Filtering
 ---------
 
@@ -125,6 +128,55 @@
   >>> len(source)
   9
 
+
+Scaling
+-------
+
+Sometimes the number of items available through a source is very large.  So
+large that you only want to access them if absolutely neccesary.  One such
+occasion is with truth-testing a source.  By default Python will call
+__nonzero__ to get the boolean value of an object, but if that isn't available
+__len__ is called to see what it returns.  That might be very expensive, so we
+want to make sure it isn't called.
+
+  >>> class MyExpensiveSource(zc.sourcefactory.basic.BasicSourceFactory):
+  ...     def getValues(self):
+  ...         yield 'a'
+  ...         raise RuntimeError('oops, iterated too far')
+
+  >>> source = MyExpensiveSource()
+
+  >>> bool(source)
+  True
+
+
+Simple case
+-----------
+
+In the most simple case, you only have to provide a method that returns a list
+of values and derive from `BasicSourceFactory`::
+
+  >>> import zc.sourcefactory.basic
+  >>> class MyStaticSource(zc.sourcefactory.basic.BasicSourceFactory):
+  ...     def getValues(self):
+  ...         return ['a', 'b', 'c']
+
+When calling the source factory, we get a source::
+
+  >>> source = MyStaticSource()
+  >>> import zope.schema.interfaces
+  >>> zope.schema.interfaces.ISource.providedBy(source)
+  True
+
+The values match our `getValues`-method of the factory::
+
+  >>> list(source)
+  ['a', 'b', 'c']
+  >>> 'a' in source
+  True
+  >>> len(source)
+  3
+
 WARNING about the standard adapters for ITerms
 ----------------------------------------------
 

Modified: zc.sourcefactory/trunk/src/zc/sourcefactory/source.py
===================================================================
--- zc.sourcefactory/trunk/src/zc/sourcefactory/source.py	2008-02-13 00:34:04 UTC (rev 83772)
+++ zc.sourcefactory/trunk/src/zc/sourcefactory/source.py	2008-02-13 03:44:40 UTC (rev 83773)
@@ -40,6 +40,11 @@
         # This is potentially expensive!
         return len(list(self._get_filtered_values()))
 
+    def __nonzero__(self):
+        for dummy in self._get_filtered_values():
+            return True
+        return False
+
     def __contains__(self, value):
         # This is potentially expensive!
         return value in self._get_filtered_values()



More information about the Checkins mailing list