rope / ropetest / objectinfertest.py

import unittest

import rope.base.project
import rope.base.builtins
from ropetest import testutils


class ObjectInferTest(unittest.TestCase):

    def setUp(self):
        super(ObjectInferTest, self).setUp()
        self.project = testutils.sample_project()
        self.pycore = self.project.get_pycore()

    def tearDown(self):
        testutils.remove_project(self.project)
        super(ObjectInferTest, self).tearDown()

    def test_simple_type_inferencing(self):
        scope = self.pycore.get_string_scope(
            'class Sample(object):\n    pass\na_var = Sample()\n')
        sample_class = scope['Sample'].get_object()
        a_var = scope['a_var'].get_object()
        self.assertEquals(sample_class, a_var.get_type())

    def test_simple_type_inferencing_classes_defined_in_holding_scope(self):
        scope = self.pycore.get_string_scope('class Sample(object):\n    pass\n' +
                                             'def a_func():\n    a_var = Sample()\n')
        sample_class = scope['Sample'].get_object()
        a_var = scope['a_func'].get_object().\
                        get_scope()['a_var'].get_object()
        self.assertEquals(sample_class, a_var.get_type())

    def test_simple_type_inferencing_classes_in_class_methods(self):
        code = 'class Sample(object):\n    pass\n' \
               'class Another(object):\n' \
               '    def a_method():\n        a_var = Sample()\n'
        scope = self.pycore.get_string_scope(code)
        sample_class = scope['Sample'].get_object()
        another_class = scope['Another'].get_object()
        a_var = another_class['a_method'].\
                        get_object().get_scope()['a_var'].get_object()
        self.assertEquals(sample_class, a_var.get_type())

    def test_simple_type_inferencing_class_attributes(self):
        code = 'class Sample(object):\n    pass\n' \
               'class Another(object):\n' \
               '    def __init__(self):\n        self.a_var = Sample()\n'
        scope = self.pycore.get_string_scope(code)
        sample_class = scope['Sample'].get_object()
        another_class = scope['Another'].get_object()
        a_var = another_class['a_var'].get_object()
        self.assertEquals(sample_class, a_var.get_type())

    def test_simple_type_inferencing_for_in_class_assignments(self):
        scope = self.pycore.get_string_scope('class Sample(object):\n    pass\n' +
                                             'class Another(object):\n    an_attr = Sample()\n')
        sample_class = scope['Sample'].get_object()
        another_class = scope['Another'].get_object()
        an_attr = another_class['an_attr'].get_object()
        self.assertEquals(sample_class, an_attr.get_type())

    def test_simple_type_inferencing_for_chained_assignments(self):
        mod = 'class Sample(object):\n    pass\n' \
              'copied_sample = Sample'
        mod_scope = self.project.get_pycore().get_string_scope(mod)
        sample_class = mod_scope['Sample']
        copied_sample = mod_scope['copied_sample']
        self.assertEquals(sample_class.get_object(),
                          copied_sample.get_object())

    def test_following_chained_assignments_avoiding_circles(self):
        mod = 'class Sample(object):\n    pass\n' \
              'sample_class = Sample\n' \
              'sample_class = sample_class\n'
        mod_scope = self.project.get_pycore().get_string_scope(mod)
        sample_class = mod_scope['Sample']
        sample_class_var = mod_scope['sample_class']
        self.assertEquals(sample_class.get_object(),
                          sample_class_var.get_object())

    def test_function_returned_object_static_type_inference1(self):
        src = 'class Sample(object):\n    pass\n' \
              'def a_func():\n    return Sample\n' \
              'a_var = a_func()\n'
        scope = self.project.get_pycore().get_string_scope(src)
        sample_class = scope['Sample']
        a_var = scope['a_var']
        self.assertEquals(sample_class.get_object(), a_var.get_object())

    def test_function_returned_object_static_type_inference2(self):
        src = 'class Sample(object):\n    pass\n' \
              'def a_func():\n    return Sample()\n' \
              'a_var = a_func()\n'
        scope = self.project.get_pycore().get_string_scope(src)
        sample_class = scope['Sample'].get_object()
        a_var = scope['a_var'].get_object()
        self.assertEquals(sample_class, a_var.get_type())

    def test_recursive_function_returned_object_static_type_inference(self):
        src = 'class Sample(object):\n    pass\n' \
              'def a_func():\n' \
              '    if True:\n        return Sample()\n' \
              '    else:\n        return a_func()\n' \
              'a_var = a_func()\n'
        scope = self.project.get_pycore().get_string_scope(src)
        sample_class = scope['Sample'].get_object()
        a_var = scope['a_var'].get_object()
        self.assertEquals(sample_class, a_var.get_type())

    def test_function_returned_object_using_call_special_function_static_type_inference(self):
        src = 'class Sample(object):\n' \
              '    def __call__(self):\n        return Sample\n' \
              'sample = Sample()\na_var = sample()'
        scope = self.project.get_pycore().get_string_scope(src)
        sample_class = scope['Sample']
        a_var = scope['a_var']
        self.assertEquals(sample_class.get_object(), a_var.get_object())

    def test_list_type_inferencing(self):
        src = 'class Sample(object):\n    pass\na_var = [Sample()]\n'
        scope = self.pycore.get_string_scope(src)
        sample_class = scope['Sample'].get_object()
        a_var = scope['a_var'].get_object()
        self.assertNotEquals(sample_class, a_var.get_type())

    def test_attributed_object_inference(self):
        src = 'class Sample(object):\n' \
              '    def __init__(self):\n        self.a_var = None\n' \
              '    def set(self):\n        self.a_var = Sample()\n'
        scope = self.pycore.get_string_scope(src)
        sample_class = scope['Sample'].get_object()
        a_var = sample_class['a_var'].get_object()
        self.assertEquals(sample_class, a_var.get_type())

    def test_getting_property_attributes(self):
        src = 'class A(object):\n    pass\n' \
              'def f(*args):\n    return A()\n' \
              'class B(object):\n    p = property(f)\n' \
              'a_var = B().p\n'
        pymod = self.pycore.get_string_module(src)
        a_class = pymod['A'].get_object()
        a_var = pymod['a_var'].get_object()
        self.assertEquals(a_class, a_var.get_type())

    def test_getting_property_attributes_with_method_getters(self):
        src = 'class A(object):\n    pass\n' \
              'class B(object):\n    def p_get(self):\n        return A()\n' \
              '    p = property(p_get)\n' \
              'a_var = B().p\n'
        pymod = self.pycore.get_string_module(src)
        a_class = pymod['A'].get_object()
        a_var = pymod['a_var'].get_object()
        self.assertEquals(a_class, a_var.get_type())

    def test_lambda_functions(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    pass\n'
            'l = lambda: C()\na_var = l()')
        c_class = mod['C'].get_object()
        a_var = mod['a_var'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_mixing_subscript_with_tuple_assigns(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    attr = 0\n'
            'd = {}\nd[0], b = (0, C())\n')
        c_class = mod['C'].get_object()
        a_var = mod['b'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_mixing_ass_attr_with_tuple_assignment(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    attr = 0\n'
            'c = C()\nc.attr, b = (0, C())\n')
        c_class = mod['C'].get_object()
        a_var = mod['b'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_mixing_slice_with_tuple_assigns(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    attr = 0\n'
            'd = [None] * 3\nd[0:2], b = ((0,), C())\n')
        c_class = mod['C'].get_object()
        a_var = mod['b'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_nested_tuple_assignments(self):
        mod = self.pycore.get_string_module(
            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
            'a, (b, c) = (C1(), (C2(), C1()))\n')
        c1_class = mod['C1'].get_object()
        c2_class = mod['C2'].get_object()
        a_var = mod['a'].get_object()
        b_var = mod['b'].get_object()
        c_var = mod['c'].get_object()
        self.assertEquals(c1_class, a_var.get_type())
        self.assertEquals(c2_class, b_var.get_type())
        self.assertEquals(c1_class, c_var.get_type())

    def test_empty_tuples(self):
        mod = self.pycore.get_string_module(
            't = ()\n'
            'a, b = t\n')
        a = mod['a'].get_object()

    def test_handling_generator_functions(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    pass\ndef f():\n    yield C()\n'
            'for c in f():\n    a_var = c\n')
        c_class = mod['C'].get_object()
        a_var = mod['a_var'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_handling_generator_functions_for_strs(self):
        mod = testutils.create_module(self.project, 'mod')
        mod.write('def f():\n    yield ""\n'
                  'for s in f():\n    a_var = s\n')
        pymod = self.pycore.resource_to_pyobject(mod)
        a_var = pymod['a_var'].get_object()
        self.assertTrue(isinstance(a_var.get_type(), rope.base.builtins.Str))

    def test_considering_nones_to_be_unknowns(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    pass\n'
            'a_var = None\na_var = C()\na_var = None\n')
        c_class = mod['C'].get_object()
        a_var = mod['a_var'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_basic_list_comprehensions(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    pass\n'
            'l = [C() for i in range(1)]\na_var = l[0]\n')
        c_class = mod['C'].get_object()
        a_var = mod['a_var'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_basic_generator_expressions(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    pass\n'
            'l = (C() for i in range(1))\na_var = list(l)[0]\n')
        c_class = mod['C'].get_object()
        a_var = mod['a_var'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_list_comprehensions_and_loop_var(self):
        mod = self.pycore.get_string_module(
            'class C(object):\n    pass\n'
            'c_objects = [C(), C()]\n'
            'l = [c for c in c_objects]\na_var = l[0]\n')
        c_class = mod['C'].get_object()
        a_var = mod['a_var'].get_object()
        self.assertEquals(c_class, a_var.get_type())

    def test_list_comprehensions_and_multiple_loop_var(self):
        mod = self.pycore.get_string_module(
            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
            'l = [(c1, c2) for c1 in [C1()] for c2 in [C2()]]\n'
            'a, b = l[0]\n')
        c1_class = mod['C1'].get_object()
        c2_class = mod['C2'].get_object()
        a_var = mod['a'].get_object()
        b_var = mod['b'].get_object()
        self.assertEquals(c1_class, a_var.get_type())
        self.assertEquals(c2_class, b_var.get_type())

    def test_list_comprehensions_and_multiple_iters(self):
        mod = self.pycore.get_string_module(
            'class C1(object):\n    pass\nclass C2(object):\n    pass\n'
            'l = [(c1, c2) for c1, c2 in [(C1(), C2())]]\n'
            'a, b = l[0]\n')
        c1_class = mod['C1'].get_object()
        c2_class = mod['C2'].get_object()
        a_var = mod['a'].get_object()
        b_var = mod['b'].get_object()
        self.assertEquals(c1_class, a_var.get_type())
        self.assertEquals(c2_class, b_var.get_type())

    def test_we_know_the_type_of_catched_exceptions(self):
        mod = self.pycore.get_string_module(
            'class MyError(Exception):\n    pass\n'
            'try:\n    raise MyError()\nexcept MyError, e:\n    pass\n')
        my_error = mod['MyError'].get_object()
        e_var = mod['e'].get_object()
        self.assertEquals(my_error, e_var.get_type())

    def test_we_know_the_type_of_catched_multiple_excepts(self):
        mod = self.pycore.get_string_module(
            'class MyError(Exception):\n    pass\n'
            'try:\n    raise MyError()\n'
            'except (MyError, Exception), e:\n    pass\n')
        my_error = mod['MyError'].get_object()
        e_var = mod['e'].get_object()
        self.assertEquals(my_error, e_var.get_type())

    # TODO: properties as decorators
    def xxx_test_using_property_as_decorators(self):
        mod = self.pycore.get_string_module(
            'class A(object):\n    pass\n'
            'class B(object):\n    '
            '@property\n    def f(self):\n        return A()\n'
            'b = B()\nvar = b.f\n')
        var = mod['var'].get_object()
        a = mod['A'].get_object()
        self.assertEquals(a, var.get_type())


def suite():
    result = unittest.TestSuite()
    result.addTests(unittest.makeSuite(ObjectInferTest))
    return result


if __name__ == '__main__':
    unittest.main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.