summaryrefslogtreecommitdiff
path: root/test/sql/test_operators.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-01-04 14:04:15 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2022-01-04 16:40:35 -0500
commit63eeec396e5d180e11a342920e7c3e49be434eb1 (patch)
tree02e203f26828018189ef20d0ff73fcc70f61c386 /test/sql/test_operators.py
parent400bf1716f84821d63daaf0a988d725dfd55d6a0 (diff)
downloadsqlalchemy-63eeec396e5d180e11a342920e7c3e49be434eb1.tar.gz
implement python_impl to custom_op for basic ORM evaluator extensibility
Added new parameter :paramref:`_sql.Operators.op.python_impl`, available from :meth:`_sql.Operators.op` and also when using the :class:`_sql.Operators.custom_op` constructor directly, which allows an in-Python evaluation function to be provided along with the custom SQL operator. This evaluation function becomes the implementation used when the operator object is used given plain Python objects as operands on both sides, and in particular is compatible with the ``synchronize_session='evaluate'`` option used with :ref:`orm_expression_update_delete`. Fixes: #3162 Change-Id: If46ba6a0e303e2180a177ba418a8cafe9b42608e
Diffstat (limited to 'test/sql/test_operators.py')
-rw-r--r--test/sql/test_operators.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py
index 9e47f217f..2c77c39f3 100644
--- a/test/sql/test_operators.py
+++ b/test/sql/test_operators.py
@@ -55,6 +55,7 @@ from sqlalchemy.sql.expression import union
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing import combinations
from sqlalchemy.testing import eq_
+from sqlalchemy.testing import expect_raises_message
from sqlalchemy.testing import expect_warnings
from sqlalchemy.testing import fixtures
from sqlalchemy.testing import is_
@@ -3286,6 +3287,28 @@ class CustomOpTest(fixtures.TestBase):
)
is_(expr.type, some_return_type)
+ def test_python_impl(self):
+ """test #3162"""
+ c = column("x")
+ c2 = column("y")
+ op1 = c.op("$", python_impl=lambda a, b: a > b)(c2).operator
+
+ is_(op1(3, 5), False)
+ is_(op1(5, 3), True)
+
+ def test_python_impl_not_present(self):
+ """test #3162"""
+ c = column("x")
+ c2 = column("y")
+ op1 = c.op("$")(c2).operator
+
+ with expect_raises_message(
+ exc.InvalidRequestError,
+ r"Custom operator '\$' can't be used with plain Python objects "
+ "unless it includes the 'python_impl' parameter.",
+ ):
+ op1(3, 5)
+
class TupleTypingTest(fixtures.TestBase):
def _assert_types(self, expr):