.. changelog::
:version: 0.8.2
+ .. change::
+ :tags: bug, sql
+ :tickets: 2726
+
+ Removed the "not implemented" ``__iter__()`` call from the base
+ :class:`.ColumnOperators` class, while this was introduced
+ in 0.8.0 to prevent an endless, memory-growing loop when one also
+ implements a ``__getitem__()`` method on a custom
+ operator and then calls erroneously ``list()`` on that object,
+ it had the effect of causing column elements to report that they
+ were in fact iterable types which then throw an error when you try
+ to iterate. There's no real way to have both sides here so we
+ stick with Python best practices. Careful with implementing
+ ``__getitem__()`` on your custom operators!
+
.. change::
:tags: feature, orm
:tickets: 2736
"""
return self.operate(neg)
- def __iter__(self):
- """Block calls to list() from calling __getitem__() endlessly."""
-
- raise NotImplementedError("Class %s is not iterable" % self.__class__)
-
def __getitem__(self, index):
"""Implement the [] operator.
sqlite, mssql
from sqlalchemy import util
import datetime
-
+import collections
from sqlalchemy import text, literal_column
class LoopOperate(operators.ColumnOperators):
"x -> :x_1"
)
- def test_no_endless_list_call(self):
+ @testing.requires.python26
+ def test_op_not_an_iterator(self):
+ # see [ticket:2726]
class MyType(UserDefinedType):
class comparator_factory(UserDefinedType.Comparator):
def __getitem__(self, index):
return self.op("->")(index)
- assert_raises_message(
- NotImplementedError,
- "Class <class 'sqlalchemy.schema.Column'> is not iterable",
- list, Column('x', MyType())
- )
+ col = Column('x', MyType())
+ assert not isinstance(col, collections.Iterable)
def test_lshift(self):
class MyType(UserDefinedType):