From: Mike Bayer Date: Tue, 4 Sep 2012 14:44:37 +0000 (-0400) Subject: `lshift` (<<) and `rshift` (>>) are also supported as optional operators. X-Git-Tag: rel_0_8_0b1~175 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bc9ff8fcc9e13fe50714c95e3f56c9144aba94f5;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git `lshift` (<<) and `rshift` (>>) are also supported as optional operators. --- diff --git a/CHANGES b/CHANGES index aa4e0bfc1b..c81022aa3b 100644 --- a/CHANGES +++ b/CHANGES @@ -421,7 +421,9 @@ underneath "0.7.xx". for end-user definition of custom __getitem__ schemes which can be applied at the type level as well as within ORM-level custom - operator schemes. + operator schemes. `lshift` (<<) + and `rshift` (>>) are also supported as + optional operators. Note that this change has the effect that descriptor-based __getitem__ schemes used by diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 4edbeafe24..7ef8e5b537 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -2107,6 +2107,8 @@ class _DefaultColumnComparator(operators.ColumnOperators): "between_op": (_between_impl, ), "neg": (_neg_impl,), "getitem": (_unsupported_impl,), + "lshift": (_unsupported_impl,), + "rshift": (_unsupported_impl,), } diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index ba33d016aa..38936231dc 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -11,7 +11,7 @@ from operator import ( and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg, - getitem + getitem, lshift, rshift ) # Py2K @@ -315,6 +315,24 @@ class ColumnOperators(Operators): """ return self.operate(getitem, index) + def __lshift__(self, other): + """implement the << operator. + + Not used by SQLAlchemy core, this is provided + for custom operator systems which want to use + << as an extension point. + """ + return self.operate(lshift, other) + + def __rshift__(self, other): + """implement the >> operator. + + Not used by SQLAlchemy core, this is provided + for custom operator systems which want to use + >> as an extension point. + """ + return self.operate(rshift, other) + def concat(self, other): """Implement the 'concat' operator. diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py index 69a22172f0..5b7aa67acb 100644 --- a/test/sql/test_operators.py +++ b/test/sql/test_operators.py @@ -7,7 +7,7 @@ from sqlalchemy.sql.expression import BinaryExpression, \ from sqlalchemy.sql import operators from sqlalchemy import exc from sqlalchemy.schema import Column, Table, MetaData -from sqlalchemy.types import Integer, TypeEngine, TypeDecorator +from sqlalchemy.types import Integer, TypeEngine, TypeDecorator, UserDefinedType from sqlalchemy.dialects import mysql, firebird from sqlalchemy import text, literal_column @@ -239,6 +239,42 @@ class NewOperatorTest(_CustomComparatorTests, fixtures.TestBase): def _assert_not_add_override(self, expr): assert not hasattr(expr, "foob") +class ExtensionOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL): + __dialect__ = 'default' + + def test_getitem(self): + class MyType(UserDefinedType): + class comparator_factory(UserDefinedType.Comparator): + def __getitem__(self, index): + return self.op("->")(index) + + self.assert_compile( + Column('x', MyType())[5], + "x -> :x_1" + ) + + def test_lshift(self): + class MyType(UserDefinedType): + class comparator_factory(UserDefinedType.Comparator): + def __lshift__(self, other): + return self.op("->")(other) + + self.assert_compile( + Column('x', MyType()) << 5, + "x -> :x_1" + ) + + def test_rshift(self): + class MyType(UserDefinedType): + class comparator_factory(UserDefinedType.Comparator): + def __rshift__(self, other): + return self.op("->")(other) + + self.assert_compile( + Column('x', MyType()) >> 5, + "x -> :x_1" + ) + from sqlalchemy import and_, not_, between class OperatorPrecedenceTest(fixtures.TestBase, testing.AssertsCompiledSQL):