From: Mike Bayer Date: Fri, 31 Oct 2008 21:44:34 +0000 (+0000) Subject: - util.flatten_iterator() func doesn't interpret strings with X-Git-Tag: rel_0_5rc3~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed3e3f257126ac07f8f07367a50b3399acd85070;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - util.flatten_iterator() func doesn't interpret strings with __iter__() methods as iterators, such as in pypy [ticket:1077]. --- diff --git a/CHANGES b/CHANGES index b022671dc6..54409f31b8 100644 --- a/CHANGES +++ b/CHANGES @@ -82,7 +82,11 @@ CHANGES - No longer expects include_columns in table reflection to be lower case. - + +- misc + - util.flatten_iterator() func doesn't interpret strings with + __iter__() methods as iterators, such as in pypy [ticket:1077]. + 0.5.0rc2 ======== - orm diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index 237772a407..01d2c738d2 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -211,10 +211,10 @@ else: def flatten_iterator(x): """Given an iterator of which further sub-elements may also be iterators, flatten the sub-elements into a single iterator. - """ + """ for elem in x: - if hasattr(elem, '__iter__'): + if not isinstance(elem, basestring) and hasattr(elem, '__iter__'): for y in flatten_iterator(elem): yield y else: diff --git a/test/base/utils.py b/test/base/utils.py index a28af90ed5..c3d026f045 100644 --- a/test/base/utils.py +++ b/test/base/utils.py @@ -92,6 +92,21 @@ class ColumnCollectionTest(TestBase): class ImmutableSubclass(str): pass +class FlattenIteratorTest(TestBase): + def test_flatten(self): + assert list(util.flatten_iterator([[1,2,3], [4,5,6], 7, 8])) == [1,2,3,4,5,6,7,8] + + def test_str_with_iter(self): + """ensure that a str object with an __iter__ method (like in PyPy) is not interpreted + as an iterable. + + """ + class IterString(str): + def __iter__(self): + return iter(self + "") + + assert list(util.flatten_iterator([IterString("asdf"), [IterString("x"), IterString("y")]])) == ["asdf", "x", "y"] + class HashOverride(object): def __init__(self, value=None): self.value = value