예제 #1
0
    def test_is_subtype(self) -> None:
        ast_nodes = builder.extract_node("""
        class int_subclass(int):
            pass
        class A(object): pass #@
        class B(A): pass #@
        class C(A): pass #@
        int_subclass() #@
        """)
        assert isinstance(ast_nodes, list)
        cls_a = ast_nodes[0]
        cls_b = ast_nodes[1]
        cls_c = ast_nodes[2]
        int_subclass = ast_nodes[3]
        int_subclass = helpers.object_type(next(int_subclass.infer()))
        base_int = self._extract("int")
        self.assertTrue(helpers.is_subtype(int_subclass, base_int))
        self.assertTrue(helpers.is_supertype(base_int, int_subclass))

        self.assertTrue(helpers.is_supertype(cls_a, cls_b))
        self.assertTrue(helpers.is_supertype(cls_a, cls_c))
        self.assertTrue(helpers.is_subtype(cls_b, cls_a))
        self.assertTrue(helpers.is_subtype(cls_c, cls_a))
        self.assertFalse(helpers.is_subtype(cls_a, cls_b))
        self.assertFalse(helpers.is_subtype(cls_a, cls_b))
예제 #2
0
 def test_is_subtype_supertype_unrelated_classes(self) -> None:
     cls_a, cls_b = builder.extract_node("""
     class A(object): pass #@
     class B(object): pass #@
     """)
     self.assertFalse(helpers.is_subtype(cls_a, cls_b))
     self.assertFalse(helpers.is_subtype(cls_b, cls_a))
     self.assertFalse(helpers.is_supertype(cls_a, cls_b))
     self.assertFalse(helpers.is_supertype(cls_b, cls_a))
예제 #3
0
 def test_is_subtype_supertype_unrelated_classes(self):
     cls_a, cls_b = test_utils.extract_node('''
     class A(object): pass #@
     class B(object): pass #@
     ''')
     self.assertFalse(helpers.is_subtype(cls_a, cls_b))
     self.assertFalse(helpers.is_subtype(cls_b, cls_a))
     self.assertFalse(helpers.is_supertype(cls_a, cls_b))
     self.assertFalse(helpers.is_supertype(cls_b, cls_a))
예제 #4
0
 def test_is_subtype_supertype_unrelated_classes(self):
     cls_a, cls_b = builder.extract_node('''
     class A(object): pass #@
     class B(object): pass #@
     ''')
     self.assertFalse(helpers.is_subtype(cls_a, cls_b))
     self.assertFalse(helpers.is_subtype(cls_b, cls_a))
     self.assertFalse(helpers.is_supertype(cls_a, cls_b))
     self.assertFalse(helpers.is_supertype(cls_b, cls_a))
예제 #5
0
 def test_is_subtype_supertype_unknown_bases(self):
     cls_a, cls_b = builder.extract_node('''
     from unknown import Unknown
     class A(Unknown): pass #@
     class B(A): pass #@
     ''')
     with self.assertRaises(exceptions._NonDeducibleTypeHierarchy):
         helpers.is_subtype(cls_a, cls_b)
     with self.assertRaises(exceptions._NonDeducibleTypeHierarchy):
         helpers.is_supertype(cls_a, cls_b)
예제 #6
0
 def test_is_subtype_supertype_unknown_bases(self):
     cls_a, cls_b = builder.extract_node('''
     from unknown import Unknown
     class A(Unknown): pass #@
     class B(A): pass #@
     ''')
     with self.assertRaises(exceptions._NonDeducibleTypeHierarchy):
         helpers.is_subtype(cls_a, cls_b)
     with self.assertRaises(exceptions._NonDeducibleTypeHierarchy):
         helpers.is_supertype(cls_a, cls_b)
예제 #7
0
 def test_is_subtype_supertype_unknown_bases(self) -> None:
     cls_a, cls_b = builder.extract_node("""
     from unknown import Unknown
     class A(Unknown): pass #@
     class B(A): pass #@
     """)
     with self.assertRaises(_NonDeducibleTypeHierarchy):
         helpers.is_subtype(cls_a, cls_b)
     with self.assertRaises(_NonDeducibleTypeHierarchy):
         helpers.is_supertype(cls_a, cls_b)
예제 #8
0
 def test_is_subtype_supertype_old_style_classes(self):
     cls_a, cls_b = builder.extract_node('''
     class A: #@
         pass
     class B(A): #@
         pass
     ''')
     self.assertFalse(helpers.is_subtype(cls_a, cls_b))
     self.assertFalse(helpers.is_subtype(cls_b, cls_a))
     self.assertFalse(helpers.is_supertype(cls_a, cls_b))
     self.assertFalse(helpers.is_supertype(cls_b, cls_a))
예제 #9
0
 def test_is_subtype_supertype_old_style_classes(self):
     cls_a, cls_b = builder.extract_node('''
     class A: #@
         pass
     class B(A): #@
         pass
     ''')
     self.assertFalse(helpers.is_subtype(cls_a, cls_b))
     self.assertFalse(helpers.is_subtype(cls_b, cls_a))
     self.assertFalse(helpers.is_supertype(cls_a, cls_b))
     self.assertFalse(helpers.is_supertype(cls_b, cls_a))
예제 #10
0
 def test_is_subtype_supertype_mro_error(self):
     cls_e, cls_f = test_utils.extract_node('''
     class A(object): pass
     class B(A): pass
     class C(A): pass
     class D(B, C): pass
     class E(C, B): pass #@
     class F(D, E): pass #@
     ''')
     self.assertFalse(helpers.is_subtype(cls_e, cls_f))
     self.assertEqual(helpers.is_subtype(cls_f, cls_e), util.Uninferable)
     self.assertEqual(helpers.is_supertype(cls_e, cls_f), util.Uninferable)
     self.assertFalse(helpers.is_supertype(cls_f, cls_e))
예제 #11
0
    def test_is_subtype_supertype_mro_error(self) -> None:
        cls_e, cls_f = builder.extract_node("""
        class A(object): pass
        class B(A): pass
        class C(A): pass
        class D(B, C): pass
        class E(C, B): pass #@
        class F(D, E): pass #@
        """)
        self.assertFalse(helpers.is_subtype(cls_e, cls_f))

        self.assertFalse(helpers.is_subtype(cls_e, cls_f))
        with self.assertRaises(_NonDeducibleTypeHierarchy):
            helpers.is_subtype(cls_f, cls_e)
        self.assertFalse(helpers.is_supertype(cls_f, cls_e))
예제 #12
0
    def test_is_subtype_supertype_mro_error(self):
        cls_e, cls_f = builder.extract_node('''
        class A(object): pass
        class B(A): pass
        class C(A): pass
        class D(B, C): pass
        class E(C, B): pass #@
        class F(D, E): pass #@
        ''')
        self.assertFalse(helpers.is_subtype(cls_e, cls_f))

        self.assertFalse(helpers.is_subtype(cls_e, cls_f))
        with self.assertRaises(exceptions._NonDeducibleTypeHierarchy):
            helpers.is_subtype(cls_f, cls_e)
        self.assertFalse(helpers.is_supertype(cls_f, cls_e))
예제 #13
0
파일: inference.py 프로젝트: tcwz/astroid
def infer_attribute(self, context=None):
    """infer an Attribute node by using getattr on the associated object"""
    for owner in self.expr.infer(context):
        if owner is util.Uninferable:
            yield owner
            continue

        if context and context.boundnode:
            # This handles the situation where the attribute is accessed through a subclass
            # of a base class and the attribute is defined at the base class's level,
            # by taking in consideration a redefinition in the subclass.
            if (isinstance(owner, bases.Instance)
                    and isinstance(context.boundnode, bases.Instance)):
                try:
                    if helpers.is_subtype(helpers.object_type(context.boundnode),
                                          helpers.object_type(owner)):
                        owner = context.boundnode
                except exceptions._NonDeducibleTypeHierarchy:
                    # Can't determine anything useful.
                    pass

        try:
            context.boundnode = owner
            yield from owner.igetattr(self.attrname, context)
            context.boundnode = None
        except (exceptions.AttributeInferenceError, exceptions.InferenceError):
            context.boundnode = None
        except AttributeError:
            # XXX method / function
            context.boundnode = None
    # Explicit StopIteration to return error information, see comment
    # in raise_if_nothing_inferred.
    return dict(node=self, context=context)
예제 #14
0
파일: inference.py 프로젝트: byd913/vim
def _get_binop_flow(left, left_type, binary_opnode, right, right_type,
                    context, reverse_context):
    """Get the flow for binary operations.

    The rules are a bit messy:

        * if left and right have the same type, then only one
          method will be called, left.__op__(right)
        * if left and right are unrelated typewise, then first
          left.__op__(right) is tried and if this does not exist
          or returns NotImplemented, then right.__rop__(left) is tried.
        * if left is a subtype of right, then only left.__op__(right)
          is tried.
        * if left is a supertype of right, then right.__rop__(left)
          is first tried and then left.__op__(right)
    """
    op = binary_opnode.op
    if _same_type(left_type, right_type):
        methods = [_bin_op(left, binary_opnode, op, right, context)]
    elif helpers.is_subtype(left_type, right_type):
        methods = [_bin_op(left, binary_opnode, op, right, context)]
    elif helpers.is_supertype(left_type, right_type):
        methods = [_bin_op(right, binary_opnode, op, left, reverse_context, reverse=True),
                   _bin_op(left, binary_opnode, op, right, context)]
    else:
        methods = [_bin_op(left, binary_opnode, op, right, context),
                   _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True)]
    return methods
예제 #15
0
파일: inference.py 프로젝트: tcwz/astroid
def _get_aug_flow(left, left_type, aug_opnode, right, right_type,
                  context, reverse_context):
    """Get the flow for augmented binary operations.

    The rules are a bit messy:

        * if left and right have the same type, then left.__augop__(right)
          is first tried and then left.__op__(right).
        * if left and right are unrelated typewise, then
          left.__augop__(right) is tried, then left.__op__(right)
          is tried and then right.__rop__(left) is tried.
        * if left is a subtype of right, then left.__augop__(right)
          is tried and then left.__op__(right).
        * if left is a supertype of right, then left.__augop__(right)
          is tried, then right.__rop__(left) and then
          left.__op__(right)
    """
    bin_op = aug_opnode.op.strip("=")
    aug_op = aug_opnode.op
    if _same_type(left_type, right_type):
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(left, aug_opnode, bin_op, right, context)]
    elif helpers.is_subtype(left_type, right_type):
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(left, aug_opnode, bin_op, right, context)]
    elif helpers.is_supertype(left_type, right_type):
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True),
                   _bin_op(left, aug_opnode, bin_op, right, context)]
    else:
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(left, aug_opnode, bin_op, right, context),
                   _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True)]
    return methods
예제 #16
0
파일: inference.py 프로젝트: byd913/vim
def _get_aug_flow(left, left_type, aug_opnode, right, right_type,
                  context, reverse_context):
    """Get the flow for augmented binary operations.

    The rules are a bit messy:

        * if left and right have the same type, then left.__augop__(right)
          is first tried and then left.__op__(right).
        * if left and right are unrelated typewise, then
          left.__augop__(right) is tried, then left.__op__(right)
          is tried and then right.__rop__(left) is tried.
        * if left is a subtype of right, then left.__augop__(right)
          is tried and then left.__op__(right).
        * if left is a supertype of right, then left.__augop__(right)
          is tried, then right.__rop__(left) and then
          left.__op__(right)
    """
    bin_op = aug_opnode.op.strip("=")
    aug_op = aug_opnode.op
    if _same_type(left_type, right_type):
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(left, aug_opnode, bin_op, right, context)]
    elif helpers.is_subtype(left_type, right_type):
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(left, aug_opnode, bin_op, right, context)]
    elif helpers.is_supertype(left_type, right_type):
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True),
                   _bin_op(left, aug_opnode, bin_op, right, context)]
    else:
        methods = [_aug_op(left, aug_opnode, aug_op, right, context),
                   _bin_op(left, aug_opnode, bin_op, right, context),
                   _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True)]
    return methods
예제 #17
0
파일: inference.py 프로젝트: byd913/vim
def infer_attribute(self, context=None):
    """infer an Attribute node by using getattr on the associated object"""
    for owner in self.expr.infer(context):
        if owner is util.Uninferable:
            yield owner
            continue

        if context and context.boundnode:
            # This handles the situation where the attribute is accessed through a subclass
            # of a base class and the attribute is defined at the base class's level,
            # by taking in consideration a redefinition in the subclass.
            if (isinstance(owner, bases.Instance)
                    and isinstance(context.boundnode, bases.Instance)):
                try:
                    if helpers.is_subtype(helpers.object_type(context.boundnode),
                                          helpers.object_type(owner)):
                        owner = context.boundnode
                except exceptions._NonDeducibleTypeHierarchy:
                    # Can't determine anything useful.
                    pass

        try:
            context.boundnode = owner
            for obj in owner.igetattr(self.attrname, context):
                yield obj
            context.boundnode = None
        except (exceptions.AttributeInferenceError, exceptions.InferenceError):
            context.boundnode = None
        except AttributeError:
            # XXX method / function
            context.boundnode = None
    # Explicit StopIteration to return error information, see comment
    # in raise_if_nothing_inferred.
    raise StopIteration(dict(node=self, context=context))
예제 #18
0
def _get_binop_flow(
    left, left_type, binary_opnode, right, right_type, context, reverse_context
):
    """Get the flow for binary operations.

    The rules are a bit messy:

        * if left and right have the same type, then only one
          method will be called, left.__op__(right)
        * if left and right are unrelated typewise, then first
          left.__op__(right) is tried and if this does not exist
          or returns NotImplemented, then right.__rop__(left) is tried.
        * if left is a subtype of right, then only left.__op__(right)
          is tried.
        * if left is a supertype of right, then right.__rop__(left)
          is first tried and then left.__op__(right)
    """
    op = binary_opnode.op
    if _same_type(left_type, right_type):
        methods = [_bin_op(left, binary_opnode, op, right, context)]
    elif helpers.is_subtype(left_type, right_type):
        methods = [_bin_op(left, binary_opnode, op, right, context)]
    elif helpers.is_supertype(left_type, right_type):
        methods = [
            _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True),
            _bin_op(left, binary_opnode, op, right, context),
        ]
    else:
        methods = [
            _bin_op(left, binary_opnode, op, right, context),
            _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True),
        ]
    return methods
예제 #19
0
 def test_is_subtype_supertype_classes_metaclasses(self):
     cls_a = builder.extract_node('''
     class A(type): #@
         pass
     ''')
     builtin_type = self._extract('type')
     self.assertTrue(helpers.is_supertype(builtin_type, cls_a))
     self.assertTrue(helpers.is_subtype(cls_a, builtin_type))
예제 #20
0
 def test_is_subtype_supertype_classes_no_type_ancestor(self):
     cls_a = builder.extract_node('''
     class A(object): #@
         pass
     ''')
     builtin_type = self._extract('type')
     self.assertFalse(helpers.is_supertype(builtin_type, cls_a))
     self.assertFalse(helpers.is_subtype(cls_a, builtin_type))
예제 #21
0
 def test_is_subtype_supertype_unknown_bases(self):
     cls_a, cls_b = test_utils.extract_node('''
     from unknown import Unknown
     class A(Unknown): pass #@
     class B(A): pass #@
     ''')
     self.assertTrue(helpers.is_subtype(cls_b, cls_a))
     self.assertTrue(helpers.is_supertype(cls_a, cls_b))
예제 #22
0
 def test_is_subtype_supertype_classes_no_type_ancestor(self):
     cls_a = builder.extract_node('''
     class A(object): #@
         pass
     ''')
     builtin_type = self._extract('type')
     self.assertFalse(helpers.is_supertype(builtin_type, cls_a))
     self.assertFalse(helpers.is_subtype(cls_a, builtin_type))
예제 #23
0
 def test_is_subtype_supertype_classes_metaclasses(self):
     cls_a = builder.extract_node('''
     class A(type): #@
         pass
     ''')
     builtin_type = self._extract('type')
     self.assertTrue(helpers.is_supertype(builtin_type, cls_a))
     self.assertTrue(helpers.is_subtype(cls_a, builtin_type))
예제 #24
0
 def test_is_subtype_supertype_classes_no_type_ancestor(self) -> None:
     cls_a = builder.extract_node("""
     class A(object): #@
         pass
     """)
     builtin_type = self._extract("type")
     self.assertFalse(helpers.is_supertype(builtin_type, cls_a))
     self.assertFalse(helpers.is_subtype(cls_a, builtin_type))
예제 #25
0
 def test_is_subtype_supertype_classes_metaclasses(self) -> None:
     cls_a = builder.extract_node("""
     class A(type): #@
         pass
     """)
     builtin_type = self._extract("type")
     self.assertTrue(helpers.is_supertype(builtin_type, cls_a))
     self.assertTrue(helpers.is_subtype(cls_a, builtin_type))
예제 #26
0
    def test_is_subtype(self):
        ast_nodes = builder.extract_node('''
        class int_subclass(int):
            pass
        class A(object): pass #@
        class B(A): pass #@
        class C(A): pass #@
        int_subclass() #@
        ''')
        cls_a = ast_nodes[0]
        cls_b = ast_nodes[1]
        cls_c = ast_nodes[2]
        int_subclass = ast_nodes[3]
        int_subclass = helpers.object_type(next(int_subclass.infer()))
        base_int = self._extract('int')
        self.assertTrue(helpers.is_subtype(int_subclass, base_int))
        self.assertTrue(helpers.is_supertype(base_int, int_subclass))

        self.assertTrue(helpers.is_supertype(cls_a, cls_b))
        self.assertTrue(helpers.is_supertype(cls_a, cls_c))
        self.assertTrue(helpers.is_subtype(cls_b, cls_a))
        self.assertTrue(helpers.is_subtype(cls_c, cls_a))
        self.assertFalse(helpers.is_subtype(cls_a, cls_b))
        self.assertFalse(helpers.is_subtype(cls_a, cls_b))
예제 #27
0
    def test_is_subtype(self):
        ast_nodes = builder.extract_node('''
        class int_subclass(int):
            pass
        class A(object): pass #@
        class B(A): pass #@
        class C(A): pass #@
        int_subclass() #@
        ''')
        cls_a = ast_nodes[0]
        cls_b = ast_nodes[1]
        cls_c = ast_nodes[2]
        int_subclass = ast_nodes[3]
        int_subclass = helpers.object_type(next(int_subclass.infer()))
        base_int = self._extract('int')
        self.assertTrue(helpers.is_subtype(int_subclass, base_int))
        self.assertTrue(helpers.is_supertype(base_int, int_subclass))

        self.assertTrue(helpers.is_supertype(cls_a, cls_b))
        self.assertTrue(helpers.is_supertype(cls_a, cls_c))
        self.assertTrue(helpers.is_subtype(cls_b, cls_a))
        self.assertTrue(helpers.is_subtype(cls_c, cls_a))
        self.assertFalse(helpers.is_subtype(cls_a, cls_b))
        self.assertFalse(helpers.is_subtype(cls_a, cls_b))
예제 #28
0
def query_attribute(self, context=None):
    """query an Attribute node by using getattr on the associated object"""
    res = []
    for owner in self.expr.query(context):
        if owner is util.Uninferable:
            assert False

        if owner is util.Unqueryable:
            continue

        if owner.query_end:
            res.extend([owner, util.Unqueryable])
            continue

        if context and context.boundnode:
            # This handles the situation where the attribute is accessed through a subclass
            # of a base class and the attribute is defined at the base class's level,
            # by taking in consideration a redefinition in the subclass.
            if isinstance(owner, bases.Instance) and isinstance(
                    context.boundnode, bases.Instance):
                try:
                    if helpers.is_subtype(
                            helpers.object_type(context.boundnode),
                            helpers.object_type(owner),
                    ):
                        owner = context.boundnode
                except exceptions._NonDeducibleTypeHierarchy:
                    # Can't determine anything useful.
                    pass
        elif not context:
            context = contextmod.InferenceContext()

        try:
            context.boundnode = owner
            res.extend(owner.query_attr(self.attrname, context))
        except (
                exceptions.AttributeInferenceError,
                exceptions.InferenceError,
                AttributeError,
        ):
            import traceback
            traceback.print_exc()
            pass
        finally:
            context.boundnode = None
    if len(res) == 0:
        return [util.Unqueryable]
    return res
예제 #29
0
파일: utils.py 프로젝트: timgates42/pylint
def is_subclass_of(child: astroid.ClassDef, parent: astroid.ClassDef) -> bool:
    """
    Check if first node is a subclass of second node.
    :param child: Node to check for subclass.
    :param parent: Node to check for superclass.
    :returns: True if child is derived from parent. False otherwise.
    """
    if not all(isinstance(node, astroid.ClassDef) for node in (child, parent)):
        return False

    for ancestor in child.ancestors():
        try:
            if helpers.is_subtype(ancestor, parent):
                return True
        except _NonDeducibleTypeHierarchy:
            continue
    return False
예제 #30
0
def infer_attribute(self, context=None):
    """infer an Attribute node by using getattr on the associated object"""
    for owner in self.expr.infer(context):
        if owner is util.Uninferable:
            yield owner
            continue

        if context and context.boundnode:
            # This handles the situation where the attribute is accessed through a subclass
            # of a base class and the attribute is defined at the base class's level,
            # by taking in consideration a redefinition in the subclass.
            if isinstance(owner, bases.Instance) and isinstance(
                context.boundnode, bases.Instance
            ):
                try:
                    if helpers.is_subtype(
                        helpers.object_type(context.boundnode),
                        helpers.object_type(owner),
                    ):
                        owner = context.boundnode
                except _NonDeducibleTypeHierarchy:
                    # Can't determine anything useful.
                    pass
        elif not context:
            context = contextmod.InferenceContext()

        old_boundnode = context.boundnode
        try:
            context.boundnode = owner
            yield from owner.igetattr(self.attrname, context)
        except (
            AttributeInferenceError,
            InferenceError,
            AttributeError,
        ):
            pass
        finally:
            context.boundnode = old_boundnode
    return dict(node=self, context=context)