[Web-SIG] Another WSGI gotcha to be aware of

Graham Dumpleton graham.dumpleton at gmail.com
Sat Aug 25 11:24:42 CEST 2007


On 25/08/07, Robert Brewer <fumanchu at aminus.org> wrote:
>
>
>
> Hi all,
>
>  I just found another corner case in the WSGI spec
>  that I thought I'd share so you all can check your
>  WSGI components for similar problems. Basically,
>  it comes down to error handling. Here's a simple
>  example:
>
>
>  class Middleware(object):
>
>      def __init__(self, nextapp, environ, start_response):
>          try:
>              self.response = nextapp(environ, start_response)
>              self.iter_response = iter(self.response)
>              return
>          except SomeException:
>              self.close()
>
>      def close(self):
>          if hasattr(self.response, "close"):
>              self.response.close()
>
>      def __iter__(self):
>          return self
>
>      def next(self):
>          try:
>              return self.iter_response.next()
>          except AnotherException:
>              self.close()
>              raise StopIteration

A question related to this example. In what ways is using
__iter__/yield better or worse than defining next() in terms of
performance, compatibility with different Python versions etc. For
example:

class Generator:
    def __init__(self, generator, callback, environ):
        self.__generator = generator
        self.__callback = callback
        self.__environ = environ
    def __iter__(self):
        for item in self.__generator:
            yield item
    def close(self):
        if hasattr(self.__generator, 'close'):
            self.__generator.close()
        self.__callback(self.__environ)

class ExecuteOnCompletion:
    def __init__(self, application, callback):
        self.__application = application
        self.__callback = callback
    def __call__(self, environ, start_response):
        try:
            result = self.__application(environ, start_response)
        except:
            self.__callback(self.__environ)
            raise
        return Generator(result, self.__callback, environ)

Just curious.

Graham


More information about the Web-SIG mailing list