Example #1
0
class TestWarnings(InferTestCase): #{{{
    
    def setUp(self):
        self.parser = Parser()
        self.num_class = self.parser.extern_scope['num']
        self.str_class = self.parser.extern_scope['str']

    def test_nonexistent_attribute(self):
        code = makecode("""
            |class A:
            |    def __init__(self, x, y):
            |        self.x = x
            |        self.y = y
            |
            |a = A(3,4)
            |a.x = a.z
            |a.z = a.x
            |a.y = a.z
            |a.w = a.w
""")

        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        problem_symbols = {problem.symbol for problem in self.parser.problems}
        self.assertEqual(problem_symbols, {'w', 'z'})

    def test_nonexistent_function(self):
        code = makecode("""
            |class A:
            |    def __init__(self, x, y):
            |        self.x = x
            |        self.y = y
            |
            |    def fun1(self):
            |        return self.x+self.y
            |
            |a = A(3,4)
            |a.z = a.fun1()
            |a.gun1()
            |a.fun2 = a.fun1
            |a.fun2()
            |# since the problem with nonexistent gun1 is already reported, gun1 and gun2 are to be considered as
            |# any_type making all invocations and other manipulations with it legal
            |a.gun2 = a.gun1
            |a.gun2()
            |a.gun3()
""")

        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        #problem_symbols = {problem.symbol for problem in self.parser.problems}
        #self.assertEqual(problem_symbols, {'gun1', 'gun3'})

    def test_nonexistent_class(self):
        code = makecode("""
            |class A:
            |    def __init__(self, x, y):
            |        self.x = x
            |        self.y = y
            |
            |class B:
            |  pass
            |
            |a = A(1,2)
            |b = B()
            |c = C()
            |a = D()
""")

        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        problem_symbols = {problem.symbol for problem in self.parser.problems}
        self.assertEqual(problem_symbols, {'C', 'D'})
Example #2
0
class TestInfer(InferTestCase): #{{{

    def setUp(self):
        self.parser = Parser()
        self.num_class = self.parser.extern_scope['num']
        self.str_class = self.parser.extern_scope['str']
        

    def test_simple_parse(self):
        code = makecode("""
            |x = 3
            |a = 'ahoj'
            |y = 6
            |z = 3 + x
            |zz = x + y
            |b = 'jozo'
            |c = a + b
            |x = 'mumly'
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        x = module_scope.resolve('x')
        y = module_scope.resolve('y')
        z = module_scope.resolve('z')
        zz = module_scope.resolve('zz')
        a = module_scope.resolve('a')
        b = module_scope.resolve('b')
        c = module_scope.resolve('c')
        self.assertIsStr(x)
        self.assertIsNum(y)
        self.assertIsNum(z)
        self.assertIsNum(zz)
        self.assertIsStr(a)
        self.assertIsStr(b)
        self.assertIsStr(c)

    def test_fun_parse(self):
        code = makecode("""
            |def mean(x,y):
            |    return (x+y)/2

            |def gean(x,y):
            |    return x+y

            |x = 3
            |y = x+2
            |z = mean(x,y)
            |x = "jozo"
            |zz = gean(x,"fero")
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        x = module_scope.resolve('x')
        y = module_scope.resolve('y')
        z = module_scope.resolve('z')
        zz = module_scope.resolve('zz')
        self.assertIsStr(x)
        self.assertIsNum(y)
        self.assertIsNum(z)
        self.assertIsStr(zz)
    
    def test_default_object(self):
        code = makecode("""
            |class A():
            |   pass
            |a = A()
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        a = module_scope.resolve('a')
        __setattr__ = a.resolve('__setattr__', 'straight')
        self.assertEqual(__setattr__, None)
        __setattr__ = a.resolve('__setattr__', mode = 'class')
        self.assertEqual(__setattr__.node.name, '__setattr__')

    def test_closure(self):
        code = makecode("""
            |def f(x):
            |    z = x
            |    def g(y):
            |        return(x+y)
            |    return g

            |g1 = f(3)
            |g2 = f('jozo')

            |a = g1(4)
            |b = g2('fero')
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        a = module_scope.resolve('a')
        b = module_scope.resolve('b')
        self.assertIsNum(a)
        self.assertIsStr(b)


    def test_class(self):
        code = makecode("""
                |class A:
                |    def __init__(self, x, y, z):
                |        self.x = x
                |        self.y = y
                |        w = 'johnie'
                |
                |a = A(3,"ahoj", "svet")
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        a = module_scope.resolve('a')
        self.assert_no_problem();
        self.assertIsNum(a.scope['x'])
        self.assertIsStr(a.scope['y'])
        self.assertNotIn('w', a.scope)
        self.assertNotIn('z', a.scope)
        self.assertEqual(a.scope.resolve('z'),None)

    def test_override_setattr(self):
        code = makecode("""
            |class A:
            |    def __init__(self, x, y):
            |        pass
            |
            |    def __setattr__(self, attr, val):
            |        object.__setattr__(self, attr, 4)
            |
            |
            |a = A(3,4)
            |a.x = 'jozo'
            |key = 'z'
            |object.__setattr__(a,key,'jozo')
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        a = module_scope.resolve('a')
        self.assert_no_problem();
        self.assertIsNum(a.scope['x'])
        self.assertIsStr(a.scope['z'])

    def test_method_lookup(self):
        code = makecode("""
            |class A:
            |    def __init__(self, x):
            |        self.x = x

            |    def get_x(self):
            |        return self.x

            |a = A('jozo')
            |b = a.get_x()
            |a = A(3)
            |c = a.get_x()
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        self.assert_no_problem();
        a = module_scope.resolve('a')
        A = module_scope.resolve('A')
        self.assertNotIn('get_x', a.scope)
        self.assertIn('get_x', A.scope)
        b = module_scope.resolve('b')
        c = module_scope.resolve('c')
        self.assertIsStr(b)
        self.assertIsNum(c)

    def test_method_manipulation(self):
        code = makecode("""
            |class A:
            |    def __init__(self, x, y):
            |        self.x = x
            |        self.y = y
            |
            |    def fun1(self):
            |        return self.x+self.y
            |
            |
            |a = A(3,4)
            |a.fun1()
            |fun2 = a.fun1
            |a.fun3 = a.fun1
            |z2 = fun2()
            |z3 = a.fun3()
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        z2 = module_scope.resolve('z2')
        self.assertIsNum(z2)
        z3 = module_scope.resolve('z3')
        self.assertIsNum(z3)

    def test_class_closure(self):
        code = makecode("""
            |class A:
            |    def __init__(self, x):
            |        self.x = x

            |    def get_x(self):
            |        return self.x

            |a = A('jozo')
            |getx = a.get_x
            |getx_class1 = A.get_x
            |getx_class2 = A.get_x
            |x1 = getx()
            |x2 = getx_class1()
            |x3 = getx_class2(a)
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        self.assertEqual(1, len(self.parser.problems))
        self.assertEqual('getx_class1', self.parser.problems[0].symbol)
        x1 = module_scope.resolve('x1')
        x3 = module_scope.resolve('x3')
        self.assertIsStr(x1)
        self.assertIsStr(x3)

    def test_inheritance(self):
        code = makecode("""
           |class A:
           |    def __init__(self):
           |        pass
           |
           |    def get_x(self):
           |        return self.x

           |class B(A):
           |    def __init__(self):
           |        pass
           |
           |    def get_y(self):
           |        return self.y

           |b = B()
           |b.x = 'jozo'
           |b.y = 4
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        self.assertEqual(len(self.parser.problems), 0)
        b = module_scope.resolve('b')
        self.assertIsNum(b.scope['y'])
        self.assertIsStr(b.scope['x'])
        self.assertEqual(b.resolve('get_x', 'class').kind, 'func')
    
    def test_function_return(self):
        code = makecode("""
           |def g():
           |   return "ahoj"
           |
           |
           |def f():
           |    x=1
           |    y=2
           |    g()
           |    return x+y;
           |
           |z = f()
        """)
        node = ast.parse(code, mode = 'exec')
        self.parser.eval_in_root(node)
        module_scope = self.parser.root_scope
        self.assertEqual(len(self.parser.problems), 0)
        z = module_scope.resolve('z')
        self.assertIsNum(z)