diff options
author | Allan Crooks <allan@amcone.net> | 2014-04-15 17:52:58 -0400 |
---|---|---|
committer | Allan Crooks <allan@amcone.net> | 2014-04-15 17:52:58 -0400 |
commit | ab0ca3c15d293894d938e64c547e75d3497d50d3 (patch) | |
tree | 020dacb8e45adb294be221c555b86c2baab4867e | |
parent | 2210cfadff4b59b673f8762bd2561b4d3a3558fa (diff) | |
download | cherrypy-git-ab0ca3c15d293894d938e64c547e75d3497d50d3.tar.gz |
Use is_iterator function to determine if the response content is iterable, rather than just testing if it is a generator.
This is in preparation for a fix for #1288. Note - we could test against
collections.Iterator, but this seems like a cleaner way of doing it for now.
-rw-r--r-- | cherrypy/lib/__init__.py | 13 | ||||
-rw-r--r-- | cherrypy/lib/cptools.py | 5 | ||||
-rw-r--r-- | cherrypy/lib/sessions.py | 3 |
3 files changed, 17 insertions, 4 deletions
diff --git a/cherrypy/lib/__init__.py b/cherrypy/lib/__init__.py index 554b3920..2c851ec4 100644 --- a/cherrypy/lib/__init__.py +++ b/cherrypy/lib/__init__.py @@ -3,6 +3,19 @@ # Deprecated in CherryPy 3.2 -- remove in CherryPy 3.3 from cherrypy.lib.reprconf import unrepr, modules, attributes +def is_iterator(obj): + '''Returns a boolean indicating if the object provided implements + the iterator protocol (i.e. like a generator). This will return + false for objects which iterable, but not iterators themselves.''' + from types import GeneratorType + if isinstance(obj, GeneratorType): + return True + elif not hasattr(obj, '__iter__'): + return False + else: + # Types which implement the protocol must return themselves when + # invoking 'iter' upon them. + return iter(obj) is obj class file_generator(object): diff --git a/cherrypy/lib/cptools.py b/cherrypy/lib/cptools.py index 134c8e47..66c9c1b8 100644 --- a/cherrypy/lib/cptools.py +++ b/cherrypy/lib/cptools.py @@ -6,6 +6,7 @@ import re import cherrypy from cherrypy._cpcompat import basestring, md5, set, unicodestr from cherrypy.lib import httputil as _httputil +from cherrypy.lib import is_iterator # Conditional HTTP request support # @@ -493,12 +494,10 @@ def flatten(debug=False): This allows cherrypy.response.body to consist of 'nested generators'; that is, a set of generators that yield generators. """ - import types - def flattener(input): numchunks = 0 for x in input: - if not isinstance(x, types.GeneratorType): + if not is_iterator(x): numchunks += 1 yield x else: diff --git a/cherrypy/lib/sessions.py b/cherrypy/lib/sessions.py index 23115c50..42c89d8c 100644 --- a/cherrypy/lib/sessions.py +++ b/cherrypy/lib/sessions.py @@ -101,6 +101,7 @@ from cherrypy._cpcompat import copyitems, pickle, random20, unicodestr from cherrypy.lib import httputil from cherrypy.lib import lockfile from cherrypy.lib import locking +from cherrypy.lib import is_iterator missing = object() @@ -778,7 +779,7 @@ def save(): else: # If the body is not being streamed, we save the data now # (so we can release the lock). - if isinstance(response.body, types.GeneratorType): + if is_iterator(response.body): response.collapse_body() cherrypy.session.save() save.failsafe = True |