Skip to content

Commit 7fc5073

Browse files
cpcloudkszucs
authored andcommitted
feat(api): implement all bitwise operators
1 parent ff1a680 commit 7fc5073

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

ibis/expr/operations/numeric.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,41 @@ class Sin(TrigonometricUnary):
316316
@public
317317
class Tan(TrigonometricUnary):
318318
"""Returns the tangent of x"""
319+
320+
321+
@public
322+
class BitwiseNot(Unary):
323+
arg = rlz.integer
324+
output_dtype = rlz.numeric_like("args", operator.invert)
325+
326+
327+
class BitwiseBinary(Binary):
328+
left = rlz.integer
329+
right = rlz.integer
330+
331+
332+
@public
333+
class BitwiseAnd(BitwiseBinary):
334+
output_dtype = rlz.numeric_like("args", operator.and_)
335+
336+
337+
@public
338+
class BitwiseOr(BitwiseBinary):
339+
output_dtype = rlz.numeric_like("args", operator.or_)
340+
341+
342+
@public
343+
class BitwiseXor(BitwiseBinary):
344+
output_dtype = rlz.numeric_like("args", operator.xor)
345+
346+
347+
@public
348+
class BitwiseLeftShift(BitwiseBinary):
349+
output_shape = rlz.shape_like("args")
350+
output_dtype = dt.int64
351+
352+
353+
@public
354+
class BitwiseRightShift(BitwiseBinary):
355+
output_shape = rlz.shape_like("args")
356+
output_dtype = dt.int64

ibis/expr/types/numeric.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from public import public
77

8+
from ibis.common.exceptions import IbisTypeError
89
from ibis.expr.types.core import _binop
910
from ibis.expr.types.generic import Column, Scalar, Value
1011

@@ -765,6 +766,75 @@ def convert_base(
765766

766767
return ops.BaseConvert(self, from_base, to_base).to_expr()
767768

769+
def __and__(self, other: IntegerValue) -> IntegerValue | NotImplemented:
770+
"""Bitwise and `self` with `other`."""
771+
from ibis.expr import operations as ops
772+
773+
return _binop(ops.BitwiseAnd, self, other)
774+
775+
__rand__ = __and__
776+
777+
def __or__(self, other: IntegerValue) -> IntegerValue | NotImplemented:
778+
"""Bitwise or `self` with `other`."""
779+
from ibis.expr import operations as ops
780+
781+
return _binop(ops.BitwiseOr, self, other)
782+
783+
__ror__ = __or__
784+
785+
def __xor__(self, other: IntegerValue) -> IntegerValue | NotImplemented:
786+
"""Bitwise xor `self` with `other`."""
787+
from ibis.expr import operations as ops
788+
789+
return _binop(ops.BitwiseXor, self, other)
790+
791+
__rxor__ = __xor__
792+
793+
def __lshift__(self, other: IntegerValue) -> IntegerValue | NotImplemented:
794+
"""Bitwise left shift `self` with `other`."""
795+
from ibis.expr import operations as ops
796+
797+
return _binop(ops.BitwiseLeftShift, self, other)
798+
799+
def __rlshift__(
800+
self, other: IntegerValue
801+
) -> IntegerValue | NotImplemented:
802+
"""Bitwise left shift `self` with `other`."""
803+
from ibis.expr import operations as ops
804+
805+
return _binop(ops.BitwiseLeftShift, other, self)
806+
807+
def __rshift__(self, other: IntegerValue) -> IntegerValue | NotImplemented:
808+
"""Bitwise right shift `self` with `other`."""
809+
from ibis.expr import operations as ops
810+
811+
return _binop(ops.BitwiseRightShift, self, other)
812+
813+
def __rrshift__(
814+
self, other: IntegerValue
815+
) -> IntegerValue | NotImplemented:
816+
"""Bitwise right shift `self` with `other`."""
817+
from ibis.expr import operations as ops
818+
819+
return _binop(ops.BitwiseRightShift, other, self)
820+
821+
def __invert__(self) -> IntegerValue:
822+
"""Bitwise not of `self`.
823+
824+
Returns
825+
-------
826+
IntegerValue
827+
Inverted bits of `self`.
828+
"""
829+
from ibis.expr import operations as ops
830+
831+
try:
832+
node = ops.BitwiseNot(self)
833+
except (IbisTypeError, NotImplementedError):
834+
return NotImplemented
835+
else:
836+
return node.to_expr()
837+
768838

769839
@public
770840
class IntegerScalar(NumericScalar, IntegerValue):

0 commit comments

Comments
 (0)