def test_binary_operator_casts_to_constant(self): exp = PyExp._binary_operator(123, 321, "+") assert isinstance(exp, BinaryOperator) assert exp._lhs == Constant(123) assert exp._rhs == Constant(321) assert exp._operator == "+"
def test_variable_array(): a = VariableArray(3, Argument("arg")) assert a.period == (1, 1, 1) assert a.nop is False assert a.relative_step_size_to(a) == (1, 1, 1) assert a.relative_step_size_to(VariableArray(2, Argument("arg"))) is None assert a[0, 0, 0] == Subscript(Argument("arg"), Constant((0, 0, 0))) assert a[1, 2, 3] == Subscript(Argument("arg"), Constant((1, 2, 3)))
def test_ensure_py_exp(): # Passes through PyExp types unchanged foo = Argument("foo") assert ensure_py_exp(foo) is foo # Wraps other values in Constant assert ensure_py_exp(123) == Constant(123)
def test_subscript(self): a = Argument("a") c = Constant(123) s = a[c] assert isinstance(s, Subscript) assert s.exp is a assert s.key is c
def test_subs(self, exp, key): s = Subscript(exp, key) # Substitute whole subscript assert s.subs({exp[key]: Argument("bar")}) == Argument("bar") # Substitute expression assert s.subs({exp: Argument("bar")}) == Argument("bar")[123] # Substitute key assert s.subs({key: Constant(321)}) == exp[321] # Substitute nothing relevant assert s.subs({Argument("bar"): Argument("xxx")}) is s
def test_dependencies(self): ten = Constant(10) twice_ten = ten + ten twice_ten_squared = twice_ten * twice_ten one = twice_ten_squared // twice_ten_squared assert one.generate_code() == ( "def f():\n" " _{tt} = 10 + 10\n" " _{tts} = _{tt} * _{tt}\n" " return (_{tts} // _{tts})\n").format( tt=id(twice_ten), tts=id(twice_ten_squared), )
def test_binary_operators(self, operator): a = Argument("a") b = Argument("b") # Native operation exp = eval("a {} b".format(operator), {}, {"a": a, "b": b}) assert isinstance(exp, BinaryOperator) assert exp._lhs == a assert exp._rhs == b assert exp._operator == operator # RHS is not PyExp exp = eval("a {} 123".format(operator), {}, {"a": a}) assert isinstance(exp, BinaryOperator) assert exp._lhs == a assert exp._rhs == Constant(123) assert exp._operator == operator # Reverse-operator methods (and LHS is not PyExp) exp = eval("123 {} a".format(operator), {}, {"a": a}) assert isinstance(exp, BinaryOperator) assert exp._lhs == Constant(123) assert exp._rhs == a assert exp._operator == operator
def test_subs(self, lhs, rhs): b = lhs + rhs # Substitute whole subscript: NB: same object must be used in this case assert b.subs({b: Argument("bar")}) == Argument("bar") # NB: in the following we must comprae string for true equality since # BinaryOperators are compared by identity # Substitute LHS assert repr(b.subs({lhs: Argument("foo")})) == repr(Argument("foo") + rhs) # Substitute RHS assert str(b.subs({rhs: Argument("foo")})) == str(lhs + Argument("foo")) # Substitution which makes operation a no-op should not return a # BinaryOperator assert b.subs({rhs: Constant(0)}) == lhs # Substitute nothing relevant assert b.subs({Argument("bar"): Argument("xxx")}) is b
def test_eq(self): assert Constant(123) == Constant(123) assert Constant(123) != Constant(321) assert Constant(123) != Argument("foo")
def test_eq(self, exp, key): assert Subscript(exp, key) == Subscript(exp, key) assert Subscript(exp, key) != Subscript(Argument("bar"), key) assert Subscript(exp, key) != Subscript(exp, Constant(321))
def test_hash(self, exp, key): assert hash(Subscript(exp, key)) == hash(Subscript(exp, key)) assert hash(Subscript(exp, key)) != hash( Subscript(Argument("bar"), key)) assert hash(Subscript(exp, key)) != hash(Subscript(exp, Constant(321)))
def key(self): return Constant(123)
def test_eq(self): assert Argument("foo") == Argument("foo") assert Argument("foo") != Argument("bar") assert Argument("foo") != Constant("foo")
def test_subs(self): c = Constant(123) assert c.subs({Constant(123): Constant(321)}) == Constant(321) assert c.subs({Constant(321): Constant(0)}) is c
def test_repr(self): assert repr(Constant("foo")) == "Constant('foo')"
class TestBinaryOperator(object): @pytest.fixture def lhs(self): return Argument("lhs") @pytest.fixture def rhs(self): return Argument("rhs") def test_code(self, lhs, rhs): b = BinaryOperator(lhs, rhs, "+") b.set_inline(False) assert set(b.get_dependencies()) == set([lhs, rhs]) assert list(b.get_argument_names()) == [] assert b.get_definitions() == "_{} = lhs + rhs\n".format(id(b)) assert b.get_expression() == "_{}".format(id(b)) b.set_inline(True) assert set(b.get_dependencies()) == set([lhs, rhs]) assert list(b.get_argument_names()) == [] assert b.get_definitions() == "".format(id(b)) assert b.get_expression() == "(lhs + rhs)" def test_repr(self, lhs, rhs): assert repr(BinaryOperator( lhs, rhs, "<<")) == "BinaryOperator(Argument('lhs'), Argument('rhs'), '<<')" def test_subs(self, lhs, rhs): b = lhs + rhs # Substitute whole subscript: NB: same object must be used in this case assert b.subs({b: Argument("bar")}) == Argument("bar") # NB: in the following we must comprae string for true equality since # BinaryOperators are compared by identity # Substitute LHS assert repr(b.subs({lhs: Argument("foo")})) == repr(Argument("foo") + rhs) # Substitute RHS assert str(b.subs({rhs: Argument("foo")})) == str(lhs + Argument("foo")) # Substitution which makes operation a no-op should not return a # BinaryOperator assert b.subs({rhs: Constant(0)}) == lhs # Substitute nothing relevant assert b.subs({Argument("bar"): Argument("xxx")}) is b @pytest.mark.parametrize( "lhs,rhs,operator,expected", [ # Non no-op arguments (Constant(123), Constant(321), "+", None), (Constant(123), Constant(321), "-", None), (Constant(123), Constant(321), "*", None), (Constant(123), Constant(321), "<<", None), (Constant(123), Constant(321), ">>", None), (Argument("foo"), Argument("foo"), "+", None), (Argument("foo"), Argument("foo"), "-", None), (Argument("foo"), Argument("foo"), "*", None), (Argument("foo"), Argument("foo"), "<<", None), (Argument("foo"), Argument("foo"), ">>", None), # No-op addition (Argument("foo"), Constant(0), "+", Argument("foo")), (Constant(0), Argument("foo"), "+", Argument("foo")), # No-op subtraction (Argument("foo"), Constant(0), "-", Argument("foo")), # *Not* no-op subtraction (Constant(0), Argument("foo"), "-", None), # No-op multiplication (Argument("foo"), Constant(1), "*", Argument("foo")), (Constant(1), Argument("foo"), "*", Argument("foo")), (Argument("foo"), Constant(0), "*", Constant(0)), (Constant(0), Argument("foo"), "*", Constant(0)), # No-op shift (Argument("foo"), Constant(0), "<<", Argument("foo")), (Argument("foo"), Constant(0), ">>", Argument("foo")), # *Not* no-op shift! (Constant(0), Argument("foo"), "<<", None), (Constant(0), Argument("foo"), ">>", None), ]) def test_is_no_op(self, lhs, rhs, operator, expected): assert BinaryOperator.is_no_op(lhs, rhs, operator) == expected
def test_hash(self): assert hash(Constant(123)) == hash(Constant(123)) assert hash(Constant(123)) != hash(Constant(321))
def test_code(self): c = Constant("foo") assert list(c.get_dependencies()) == [] assert list(c.get_argument_names()) == [] assert c.get_definitions() == "" assert c.get_expression() == "'foo'"