Commits

Mike Bayer committed d9e6bf0

`lshift` (<<) and `rshift` (>>) are also supported as optional operators.

  • Participants
  • Parent commits 28a6c6d

Comments (0)

Files changed (4)

     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

File lib/sqlalchemy/sql/expression.py

         "between_op": (_between_impl, ),
         "neg": (_neg_impl,),
         "getitem": (_unsupported_impl,),
+        "lshift": (_unsupported_impl,),
+        "rshift": (_unsupported_impl,),
     }
 
 

File lib/sqlalchemy/sql/operators.py

 
 from operator import (
     and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg,
-    getitem
+    getitem, lshift, rshift
     )
 
 # Py2K
         """
         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.
 

File test/sql/test_operators.py

 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
     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):