"""
Testing object mode specifics.

"""
from __future__ import print_function

import numpy as np

import numba.unittest_support as unittest
from numba.compiler import compile_isolated, Flags
from numba import utils, jit
from .support import TestCase


def complex_constant(n):
    tmp = n + 4
    return tmp + 3j

def long_constant(n):
    return n + 100000000000000000000000000000000000000000000000

def delitem_usecase(x):
    del x[:]


forceobj = Flags()
forceobj.set("force_pyobject")


def loop_nest_3(x, y):
    n = 0
    for i in range(x):
        for j in range(y):
            for k in range(x+y):
                n += i * j

    return n


def array_of_object(x):
    return x


class TestObjectMode(TestCase):

    def test_complex_constant(self):
        pyfunc = complex_constant
        cres = compile_isolated(pyfunc, (), flags=forceobj)
        cfunc = cres.entry_point
        self.assertPreciseEqual(pyfunc(12), cfunc(12))

    def test_long_constant(self):
        pyfunc = long_constant
        cres = compile_isolated(pyfunc, (), flags=forceobj)
        cfunc = cres.entry_point
        self.assertPreciseEqual(pyfunc(12), cfunc(12))

    def test_loop_nest(self):
        """
        Test bug that decref the iterator early.
        If the bug occurs, a segfault should occur
        """
        pyfunc = loop_nest_3
        cres = compile_isolated(pyfunc, (), flags=forceobj)
        cfunc = cres.entry_point
        self.assertEqual(pyfunc(5, 5), cfunc(5, 5))

        def bm_pyfunc():
            pyfunc(5, 5)

        def bm_cfunc():
            cfunc(5, 5)

        print(utils.benchmark(bm_pyfunc))
        print(utils.benchmark(bm_cfunc))

    def test_array_of_object(self):
        cfunc = jit(array_of_object)
        objarr = np.array([object()] * 10)
        self.assertIs(cfunc(objarr), objarr)

    def test_sequence_contains(self):
        """
        Test handling of the `in` comparison
        """
        @jit(forceobj=True)
        def foo(x, y):
            return x in y

        self.assertTrue(foo(1, [0, 1]))
        self.assertTrue(foo(0, [0, 1]))
        self.assertFalse(foo(2, [0, 1]))

        with self.assertRaises(TypeError) as raises:
            foo(None, None)

        self.assertIn("is not iterable", str(raises.exception))

    def test_delitem(self):
        pyfunc = delitem_usecase
        cres = compile_isolated(pyfunc, (), flags=forceobj)
        cfunc = cres.entry_point

        l = [3, 4, 5]
        cfunc(l)
        self.assertPreciseEqual(l, [])
        with self.assertRaises(TypeError):
            cfunc(42)


if __name__ == '__main__':
    unittest.main()

@@ -2580,16 +2580,1547 @@
 c(42)%0A%0A%0A
+class TestObjectModeInvalidRewrite(TestCase):%0A    %22%22%22%0A    Tests to ensure that rewrite passes didn't affect objmode lowering.%0A    %22%22%22%0A%0A    def _ensure_objmode(self, disp):%0A        self.assertTrue(disp.signatures)%0A        self.assertFalse(disp.nopython_signatures)%0A        return disp%0A%0A    def test_static_raise_in_objmode_fallback(self):%0A        %22%22%22%0A        Test code based on user submitted issue at%0A        https://github.com/numba/numba/issues/2159%0A        %22%22%22%0A        def test0(n):%0A            return n%0A%0A        def test1(n):%0A            if n == 0:%0A                # static raise will fail in objmode if the IR is modified by%0A                # rewrite pass%0A                raise ValueError()%0A            return test0(n)  # trigger objmode fallback%0A%0A        compiled = jit(test1)%0A        self.assertEqual(test1(10), compiled(10))%0A        self._ensure_objmode(compiled)%0A%0A    def test_static_setitem_in_objmode_fallback(self):%0A        %22%22%22%0A        Test code based on user submitted issue at%0A        https://github.com/numba/numba/issues/2169%0A        %22%22%22%0A%0A        def test0(n):%0A            return n%0A%0A        def test(a1, a2):%0A            a1 = np.asarray(a1)%0A            # static setitem here will fail in objmode if the IR is modified by%0A            # rewrite pass%0A            a2%5B0%5D = 1%0A            return test0(a1.sum() + a2.sum())   # trigger objmode fallback%0A%0A        compiled = jit(test)%0A        args = np.array(%5B3%5D), np.array(%5B4%5D)%0A        self.assertEqual(test(*args), compiled(*args))%0A        self._ensure_objmode(compiled)%0A%0A%0A
 if __nam

Add test for #2159 and #2169. Verify that rewrite pass doesn't affect objmode lowering