From 3cfe3fd81d7ce3539633b80c99327767cebd09d5 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 19 Jul 2015 10:27:33 -0400 Subject: [PATCH] - Fixed bug where coersion of literal ``True`` or ``False`` constant in conjunction with :func:`.and_` or :func:`.or_` would fail with an AttributeError. fixes #3490 --- doc/build/changelog/changelog_10.rst | 8 ++++ lib/sqlalchemy/sql/elements.py | 7 +++- test/sql/test_operators.py | 58 ++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index c4d9ab4480..7dae2bebd8 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -18,6 +18,14 @@ .. changelog:: :version: 1.0.7 + .. change:: + :tags: bug, sql + :tickets: 3490 + + Fixed bug where coersion of literal ``True`` or ``False`` constant + in conjunction with :func:`.and_` or :func:`.or_` would fail + with an AttributeError. + .. change:: :tags: bug, sql :tickets: 3485 diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 41dfcf1478..eb0923e15a 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -1847,9 +1847,12 @@ class BooleanClauseList(ClauseList, ColumnElement): def _construct(cls, operator, continue_on, skip_on, *clauses, **kw): convert_clauses = [] - clauses = util.coerce_generator_arg(clauses) + clauses = [ + _expression_literal_as_text(clause) + for clause in + util.coerce_generator_arg(clauses) + ] for clause in clauses: - clause = _expression_literal_as_text(clause) if isinstance(clause, continue_on): continue diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py index 65d1e3716b..bb4cb1bf17 100644 --- a/test/sql/test_operators.py +++ b/test/sql/test_operators.py @@ -825,6 +825,64 @@ class ConjunctionTest(fixtures.TestBase, testing.AssertsCompiledSQL): "SELECT false AS anon_1, false AS anon_2" ) + def test_is_true_literal(self): + c = column('x', Boolean) + self.assert_compile( + c.is_(True), + "x IS true" + ) + + def test_is_false_literal(self): + c = column('x', Boolean) + self.assert_compile( + c.is_(False), + "x IS false" + ) + + def test_and_false_literal_leading(self): + self.assert_compile( + and_(False, True), + "false" + ) + + self.assert_compile( + and_(False, False), + "false" + ) + + def test_and_true_literal_leading(self): + self.assert_compile( + and_(True, True), + "true" + ) + + self.assert_compile( + and_(True, False), + "false" + ) + + def test_or_false_literal_leading(self): + self.assert_compile( + or_(False, True), + "true" + ) + + self.assert_compile( + or_(False, False), + "false" + ) + + def test_or_true_literal_leading(self): + self.assert_compile( + or_(True, True), + "true" + ) + + self.assert_compile( + or_(True, False), + "true" + ) + class OperatorPrecedenceTest(fixtures.TestBase, testing.AssertsCompiledSQL): __dialect__ = 'default' -- 2.47.3