[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