[Python-checkins] python/nondist/peps pep-0333.txt,1.16,1.17

pje at users.sourceforge.net pje at users.sourceforge.net
Fri Sep 17 18:32:24 CEST 2004


Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1269

Modified Files:
	pep-0333.txt 
Log Message:
Fixed middleware example not handling 'close' correctly.  Fixed an
erroneous statement re: calling 'write()' with empty strings.  Moved
"Multiple Invocations" note into overview, and moved "callable"
definition to overview's preface.

Index: pep-0333.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0333.txt,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- pep-0333.txt	17 Sep 2004 15:31:58 -0000	1.16
+++ pep-0333.txt	17 Sep 2004 16:32:17 -0000	1.17
@@ -132,6 +132,15 @@
 contained application, and can be used to provide extended APIs,
 content transformation, navigation, and other useful functions.
 
+Throughout this specification, we will use the term "a callable" to
+mean "a function, method, class, or an instance with a ``__call__``
+method".  It is up to the server, gateway, or application implementing
+the callable to choose the appropriate implementation technique for
+their needs.  Conversely, a server, gateway, or application that is
+invoking a callable **must not** have any dependency on what kind of
+callable was provided to it.  Callables are only to be called, not
+introspected upon.
+
 
 The Application/Framework Side
 ------------------------------
@@ -140,7 +149,9 @@
 two arguments.  The term "object" should not be misconstrued as
 requiring an actual object instance: a function, method, class,
 or instance with a ``__call__`` method are all acceptable for
-use as an application object.
+use as an application object.  Application objects must be able
+to be invoked more than once, as virtually all servers/gateways
+(other than CGI) will make such repeated requests.
 
 (Note: although we refer to it as an "application" object, this
 should not be construed to mean that application developers will use
@@ -186,15 +197,6 @@
             self.start(status, headers)
             yield "Hello world!\n"
 
-Throughout this specification, we will use the term "a callable" to
-mean "a function, method, class, or an instance with a ``__call__``
-method".  It is up to the server, gateway, or application implementing
-the callable to choose the appropriate implementation technique for
-their needs.  Conversely, a server, gateway, or application that is
-invoking a callable must *not* have any dependency on what kind of
-callable was provided to it.  Callables are only to be called, not
-introspected upon.
-
 
 The Server/Gateway Side
 -----------------------
@@ -311,30 +313,54 @@
 converts ``text/plain`` responses to pig latin, using Joe Strout's
 ``piglatin.py``.  (Note: a "real" middleware component would 
 probably use a more robust way of checking the content type, and
-should also check for a content encoding.)
+should also check for a content encoding.  Also, this simple
+example ignores the possibility that a word might be split across
+a block boundary.)
 
 ::
 
     from piglatin import piglatin
     
+    class LatinIter:
+
+        """Transform iterated output to piglatin, if it's okay to do so
+        
+        Note that the "okayness" can change until the application yields
+        its first non-empty string, so 'transform_ok' has to be a mutable
+        truth value."""
+
+		def __init__(self,result,transform_ok):
+	        if hasattr(result,'close'):
+                self.close = result.close
+            self._next = iter(result).next
+            self.transform_ok = transform_ok
+
+		def __iter__(self):
+		    return self
+		
+		def next(self):
+			if self.transform_ok:
+				return piglatin(self._next())
+			else:
+				return self._next()
+
     class Latinator:
 
         # by default, don't transform output
-        transform = str  
+        transform = False  
 
         def __init__(self, application):
             self.application = application
 
         def __call__(environ, start_response):
-
-            def write_latin(data):
-                self.write(self.transform(data))
-                
+            
+            transform_ok = []
+            
             def start_latin(status,headers,exc_info=None):
     
                 for name,value in headers:
                     if name.lower()=='content-type' and value=='text/plain':
-                        self.transform = piglatin
+                        transform_ok.append(True)
 		                # Strip content-length if present, else it'll be wrong
 		                headers = [(name,value) 
 	    	                for name,value in headers 
@@ -342,11 +368,17 @@
 	            	    ]
 	            	    break
                     
-                self.write = start_response(status,headers,exc_info)
-                return write_latin
+            	write = start_response(status,headers,exc_info)
+
+                if transform_ok:
+		            def write_latin(data):
+		                write(piglatin(data))
+	                return write_latin
+                else:
+                    return write
+
+            return LatinIter(self.application(environ,start_latin),transform_ok)
 
-            for data in self.application(environ,start_latin):
-                yield self.transform(data)
 
 	# Run foo_app under a Latinator's control, using the example CGI gateway
 	from foo_app import foo_app
@@ -672,12 +704,11 @@
 headers, please see the `Other HTTP Features`_ section below.)
 
 The ``start_response`` callable **must not** actually transmit the
-HTTP headers.  It must store them until the first ``write`` call that
-is passed a non-empty string, or until after the first iteration of
-the application return value that yields a non-empty string.  This is
-to ensure that buffered and asynchronous applications can replace
-their originally intended output with error output, up until the last
-possible moment.
+HTTP headers.  It must store them until the first ``write`` call, or
+until after the first iteration of the application return value that
+yields a non-empty string.  This is to ensure that buffered and
+asynchronous applications can replace their originally intended output
+with error output, up until the last possible moment.
 
 The ``exc_info`` argument, if supplied, must be a Python
 ``sys.exc_info()`` tuple.  This argument should be supplied by the
@@ -919,13 +950,6 @@
 this specification as a "string".
 
 
-Multiple Invocations
---------------------
-
-Application objects must be able to be invoked more than once, since
-virtually all servers/gateways will make such requests.
-
-
 Error Handling
 --------------
 



More information about the Python-checkins mailing list