summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-06-03 16:32:12 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-06-03 16:32:12 -0400
commitd993bdeac8674db88efb3c400b4a505c8f97af9e (patch)
treedafd15d9e15bf6068a4f76a91bbaafac6ddde785
parentf8325d9dbb52d0da140f3403ce915645ae4a5a9c (diff)
downloadsqlalchemy-d993bdeac8674db88efb3c400b4a505c8f97af9e.tar.gz
- remove the ``__iter__()`` with notimplemented since it interferes
with legitimate iterable detection, [ticket:2726]
-rw-r--r--doc/build/changelog/changelog_08.rst15
-rw-r--r--doc/build/changelog/changelog_09.rst15
-rw-r--r--lib/sqlalchemy/sql/operators.py5
-rw-r--r--test/sql/test_operators.py13
4 files changed, 36 insertions, 12 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index 211668867..7e8e618a4 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -7,6 +7,21 @@
: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
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst
index df87f397c..3c9682105 100644
--- a/doc/build/changelog/changelog_09.rst
+++ b/doc/build/changelog/changelog_09.rst
@@ -7,6 +7,21 @@
:version: 0.9.0
.. 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! Also in 0.8.2.
+
+ .. change::
:tags: feature, sql
:tickets: 1068
diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py
index 4afb3db48..128442158 100644
--- a/lib/sqlalchemy/sql/operators.py
+++ b/lib/sqlalchemy/sql/operators.py
@@ -313,11 +313,6 @@ class ColumnOperators(Operators):
"""
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.
diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py
index d1db733e0..b3919d0da 100644
--- a/test/sql/test_operators.py
+++ b/test/sql/test_operators.py
@@ -15,7 +15,7 @@ from sqlalchemy.dialects import mysql, firebird, postgresql, oracle, \
sqlite, mssql
from sqlalchemy import util
import datetime
-
+import collections
from sqlalchemy import text, literal_column
class LoopOperate(operators.ColumnOperators):
@@ -352,17 +352,16 @@ class ExtensionOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
"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):