예제 #1
0
    def test_single_if_else_w_following_undetermined(self):
        def impl(x):
            x_is_none_work = False
            if x is None:
                x_is_none_work = True
            else:
                dead = 7  # noqa: F841 # no effect

            if x_is_none_work:
                y = 10
            else:
                y = -3
            return y

        self.assert_prune(impl, (types.NoneType('none'), ), [False, None],
                          None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True, None], 10)

        def impl(x):
            x_is_none_work = False
            if x is None:
                x_is_none_work = True
            else:
                pass  # force the True branch exit to be on backbone

            if x_is_none_work:
                y = 10
            else:
                y = -3
            return y

        self.assert_prune(impl, (types.NoneType('none'), ), [None, None], None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True, None], 10)
예제 #2
0
    def test_single_if(self):
        def impl(x):
            if 1 == 0:
                return 3.14159

        self.assert_prune(impl, (types.NoneType('none'), ), [True], None)

        def impl(x):
            if 1 == 1:
                return 3.14159

        self.assert_prune(impl, (types.NoneType('none'), ), [False], None)

        def impl(x):
            if x is None:
                return 3.14159

        self.assert_prune(impl, (types.NoneType('none'), ), [False], None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True], 10)

        def impl(x):
            if x == 10:
                return 3.14159

        self.assert_prune(impl, (types.NoneType('none'), ), [True], None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [None], 10)

        def impl(x):
            if x == 10:
                z = 3.14159  # noqa: F841 # no effect

        self.assert_prune(impl, (types.NoneType('none'), ), [True], None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [None], 10)
예제 #3
0
    def test_double_if_else_non_literal_const(self):
        def impl(x):
            one_hundred = 100
            if x == one_hundred:
                y = 3.14159
            else:
                y = 1.61803
            return y

        # no prune as compilation specialization on literal value not permitted
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [None], 10)
        self.assert_prune(impl, (types.IntegerLiteral(100), ), [None], 100)
예제 #4
0
    def test_single_if_const_val(self):
        def impl(x):
            if x == 100:
                return 3.14159

        self.assert_prune(impl, (types.NoneType('none'), ), [True], None)
        self.assert_prune(impl, (types.IntegerLiteral(100), ), [None], 100)

        def impl(x):
            # switch the condition order
            if 100 == x:
                return 3.14159

        self.assert_prune(impl, (types.NoneType('none'), ), [True], None)
        self.assert_prune(impl, (types.IntegerLiteral(100), ), [None], 100)
예제 #5
0
    def test_single_if_else_two_const_val(self):
        def impl(x, y):
            if x == y:
                return 3.14159
            else:
                return 1.61803

        self.assert_prune(impl, (types.IntegerLiteral(100), ) * 2, [None], 100,
                          100)
        self.assert_prune(impl, (types.NoneType('none'), ) * 2, [False], None,
                          None)
        self.assert_prune(impl, (
            types.IntegerLiteral(100),
            types.NoneType('none'),
        ), [True], 100, None)
        self.assert_prune(
            impl, (types.IntegerLiteral(100), types.IntegerLiteral(1000)),
            [None], 100, 1000)
예제 #6
0
    def test_single_if_else(self):
        def impl(x):
            if x is None:
                return 3.14159
            else:
                return 1.61803

        self.assert_prune(impl, (types.NoneType('none'), ), [False], None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True], 10)
예제 #7
0
    def test_cond_is_kwarg_value(self):
        def impl(x=1000):
            if x == 1000:
                y = 10
            else:
                y = 40

            if x != 1000:
                z = 100
            else:
                z = 400

            return z, y

        self.assert_prune(impl, (types.Omitted(1000), ), [None, None], 1000)
        self.assert_prune(impl, (types.IntegerLiteral(1000), ), [None, None],
                          1000)
        self.assert_prune(impl, (types.IntegerLiteral(0), ), [None, None], 0)
        self.assert_prune(impl, (types.NoneType('none'), ), [True, False],
                          None)
예제 #8
0
    def test_single_if_else_w_following_undetermined(self):
        def impl(x):
            x_is_none_work = False
            if x is None:
                x_is_none_work = True
            else:
                dead = 7  # noqa: F841 # no effect

            if x_is_none_work:
                y = 10
            else:
                y = -3
            return y

        self.assert_prune(impl, (types.NoneType('none'), ), [False, None],
                          None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True, None], 10)

        def impl(x):
            x_is_none_work = False
            if x is None:
                x_is_none_work = True
            else:
                pass

            if x_is_none_work:
                y = 10
            else:
                y = -3
            return y

        if utils.PYVERSION >= (3, 10):
            # Python 3.10 creates a block with a NOP in it for the `pass` which
            # means it gets pruned.
            self.assert_prune(impl, (types.NoneType('none'), ), [False, None],
                              None)
        else:
            self.assert_prune(impl, (types.NoneType('none'), ), [None, None],
                              None)

        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True, None], 10)
예제 #9
0
    def test_freevar_bake_in(self):

        _FREEVAR = 123

        def impl(x):
            if _FREEVAR == 123:
                return x
            else:
                return x + 10

        self.assert_prune(impl, (types.IntegerLiteral(1), ), [False], 1)

        _FREEVAR = 12

        def impl(x):
            if _FREEVAR == 123:
                return x
            else:
                return x + 10

        self.assert_prune(impl, (types.IntegerLiteral(1), ), [True], 1)
예제 #10
0
    def test_issue_868(self):
        '''
        Summary: multiplying a scalar by a non-scalar would cause a crash in
        type inference because TimeDeltaMixOp always assumed at least one of
        its operands was an NPTimeDelta in its generic() method.
        '''
        with self.assertRaises(TypingError) as raises:
            compile_isolated(issue_868, (types.Array(types.int32, 1, 'C'),))

        expected = ((_header_lead + " Function(<built-in function mul>) found "
                     "for signature:\n \n >>> mul(UniTuple({} x 1), {})")
            .format(str(types.intp), types.IntegerLiteral(2)))
        self.assertIn(expected, str(raises.exception))
        self.assertIn("During: typing of", str(raises.exception))
예제 #11
0
    def test_issue_868(self):
        '''
        Summary: multiplying a scalar by a non-scalar would cause a crash in
        type inference because TimeDeltaMixOp always assumed at least one of
        its operands was an NPTimeDelta in its generic() method.
        '''
        with self.assertRaises(TypingError) as raises:
            compile_isolated(issue_868, (types.Array(types.int32, 1, 'C'), ))

        expected = (
            "Invalid use of Function(<built-in function mul>) with argument(s) of type(s): (UniTuple({0} x 1), {1})"
            .format(str(types.intp), types.IntegerLiteral(2)))
        self.assertIn(expected, str(raises.exception))
        self.assertIn("[1] During: typing of", str(raises.exception))
예제 #12
0
    def test_global_bake_in(self):
        def impl(x):
            if _GLOBAL == 123:
                return x
            else:
                return x + 10

        self.assert_prune(impl, (types.IntegerLiteral(1), ), [False], 1)

        global _GLOBAL
        tmp = _GLOBAL

        try:
            _GLOBAL = 5

            def impl(x):
                if _GLOBAL == 123:
                    return x
                else:
                    return x + 10

            self.assert_prune(impl, (types.IntegerLiteral(1), ), [True], 1)
        finally:
            _GLOBAL = tmp
예제 #13
0
    def test_single_two_branches_same_cond(self):
        def impl(x):
            if x is None:
                y = 10
            else:
                y = 40

            if x is not None:
                z = 100
            else:
                z = 400

            return z, y

        self.assert_prune(impl, (types.NoneType('none'), ), [False, True],
                          None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True, False],
                          10)
예제 #14
0
    def test_cond_rewrite_is_correct(self):
        # this checks that when a condition is replaced, it is replace by a
        # true/false bit that correctly represents the evaluated condition
        def fn(x):
            if x is None:
                return 10
            return 12

        def check(func, arg_tys, bit_val):
            func_ir = compile_to_ir(func)

            # check there is 1 branch
            before_branches = self.find_branches(func_ir)
            self.assertEqual(len(before_branches), 1)

            # check the condition in the branch is a binop
            pred_var = before_branches[0].cond
            pred_defn = ir_utils.get_definition(func_ir, pred_var)
            self.assertEqual(pred_defn.op, 'call')
            condition_var = pred_defn.args[0]
            condition_op = ir_utils.get_definition(func_ir, condition_var)
            self.assertEqual(condition_op.op, 'binop')

            # do the prune, this should kill the dead branch and rewrite the
            #'condition to a true/false const bit
            if self._DEBUG:
                print("=" * 80)
                print("before prune")
                func_ir.dump()
            dead_branch_prune(func_ir, arg_tys)
            if self._DEBUG:
                print("=" * 80)
                print("after prune")
                func_ir.dump()

            # after mutation, the condition should be a const value `bit_val`
            new_condition_defn = ir_utils.get_definition(
                func_ir, condition_var)
            self.assertTrue(isinstance(new_condition_defn, ir.Const))
            self.assertEqual(new_condition_defn.value, bit_val)

        check(fn, (types.NoneType('none'), ), 1)
        check(fn, (types.IntegerLiteral(10), ), 0)
예제 #15
0
    def test_cond_is_kwarg_none(self):
        def impl(x=None):
            if x is None:
                y = 10
            else:
                y = 40

            if x is not None:
                z = 100
            else:
                z = 400

            return z, y

        self.assert_prune(impl, (types.Omitted(None), ), [False, True], None)
        self.assert_prune(impl, (types.NoneType('none'), ), [False, True],
                          None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True, False],
                          10)
예제 #16
0
    def test_double_if_else_rt_const(self):
        def impl(x):
            one_hundred = 100
            x_is_none_work = 4
            if x is None:
                x_is_none_work = 100
            else:
                dead = 7  # noqa: F841 # no effect

            if x_is_none_work == one_hundred:
                y = 10
            else:
                y = -3

            return y, x_is_none_work

        self.assert_prune(impl, (types.NoneType('none'), ), [False, None],
                          None)
        self.assert_prune(impl, (types.IntegerLiteral(10), ), [True, None], 10)