--- /dev/null
+.. change::
+ :tags: bug, regression, sql
+ :tickets: 6300
+
+ Fixed regression caused by :ticket:`5395` where tuning back the check for
+ sequences in :func:`_sql.select` now caused failures when doing 2.0-style
+ querying with a mapped class that also happens to have an ``__iter__()``
+ method. Tuned the check some more to accommodate this as well as some other
+ interesting ``__iter__()`` scenarios.
+
from .visitors import InternalTraversal
from .. import exc
from .. import util
+from ..inspection import inspect
if util.TYPE_CHECKING:
from typing import Any
"""
if (
args
- and hasattr(args[0], "__iter__")
- and not isinstance(args[0], util.string_types + (ClauseElement,))
+ and (
+ isinstance(args[0], list)
+ or (
+ hasattr(args[0], "__iter__")
+ and not isinstance(
+ args[0], util.string_types + (ClauseElement,)
+ )
+ and inspect(args[0], raiseerr=False) is None
+ and not hasattr(args[0], "__clause_element__")
+ )
+ )
) or kw:
return cls.create_legacy_select(*args, **kw)
else:
"WHERE mytable.myid = myothertable.otherid",
)
+ def test_new_calling_style_clauseelement_thing_that_has_iter(self):
+ class Thing(object):
+ def __clause_element__(self):
+ return table1
+
+ def __iter__(self):
+ return iter(["a", "b", "c"])
+
+ stmt = select(Thing())
+ self.assert_compile(
+ stmt,
+ "SELECT mytable.myid, mytable.name, "
+ "mytable.description FROM mytable",
+ )
+
+ def test_new_calling_style_inspectable_ce_thing_that_has_iter(self):
+ class Thing(object):
+ def __iter__(self):
+ return iter(["a", "b", "c"])
+
+ class InspectedThing(object):
+ def __clause_element__(self):
+ return table1
+
+ from sqlalchemy.inspection import _inspects
+
+ @_inspects(Thing)
+ def _ce(thing):
+ return InspectedThing()
+
+ stmt = select(Thing())
+ self.assert_compile(
+ stmt,
+ "SELECT mytable.myid, mytable.name, "
+ "mytable.description FROM mytable",
+ )
+
+ def test_new_calling_style_thing_ok_actually_use_iter(self):
+ class Thing(object):
+ def __iter__(self):
+ return iter([table1.c.name, table1.c.description])
+
+ stmt = select(Thing())
+ self.assert_compile(
+ stmt,
+ "SELECT mytable.name, mytable.description FROM mytable",
+ )
+
def test_kw_triggers_old_style(self):
assert_raises_message(