summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cherrypy/lib/__init__.py13
-rw-r--r--cherrypy/lib/cptools.py5
-rw-r--r--cherrypy/lib/sessions.py3
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