Exemplo n.º 1
0
    def visit_getattr(self, node):
        """check that the accessed attribute exists

        to avoid to much false positives for now, we'll consider the code as
        correct if a single of the infered nodes has the accessed attribute.

        function/method, super call and metaclasses are ignored
        """
        if node.attrname in self.config.generated_members:
            # attribute is marked as generated, stop here
            return
        try:
            infered = list(node.expr.infer())
        except astng.InferenceError:
            return
        # list of (node, nodename) which are missing the attribute
        missingattr = set()
        ignoremim = self.config.ignore_mixin_members
        inference_failure = False
        for owner in infered:
            # skip yes object
            if owner is astng.YES:
                inference_failure = True
                continue
            # skip None anyway
            if isinstance(owner, astng.Const) and owner.value is None:
                continue
            # XXX "super" / metaclass call
            if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
                continue
            name = getattr(owner, 'name', 'None')
            if name in self.config.ignored_classes:
                continue
            if ignoremim and name[-5:].lower() == 'mixin':
                continue
            try:
                owner.getattr(node.attrname)
            except AttributeError:
                # XXX method / function
                continue
            except astng.NotFoundError, ex:
                if isinstance(owner, astng.Instance) \
                       and owner.has_dynamic_getattr():
                    continue
                # explicit skipping of optparse'Values class
                if owner.name == 'Values' and \
                       owner.root().name in ('optik', 'optparse'):
                    continue
                missingattr.add((owner, name))
                continue
            # stop on the first found
            break
Exemplo n.º 2
0
def _emit_no_member(owner, owner_name, attrname,
                    ignored_modules, ignored_mixins, ignored_classes):
    """Try to see if no-member should be emitted for the given owner.

    The following cases are ignored:

        * the owner is a function and it has decorators.
        * the owner is an instance and it has __getattr__, __getattribute__ implemented
        * the module is explicitly ignored from no-member checks
        * the owner is a class and the name can be found in its metaclass.
    """
    if owner_name in ignored_classes:
        return False
    # skip None anyway
    if isinstance(owner, astroid.Const) and owner.value is None:
        return False
    # TODO(cpopa): This should be removed when we'll understand "super"
    if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
        return False
    if ignored_mixins and owner_name[-5:].lower() == 'mixin':
        return False
    if isinstance(owner, astroid.Function) and owner.decorators:
        return False
    if isinstance(owner, Instance):
        if owner.has_dynamic_getattr() or not has_known_bases(owner):
            return False
    # explicit skipping of module member access
    if owner.root().name in ignored_modules:
        return False
    if isinstance(owner, astroid.Class):
        # Look up in the metaclass only if the owner is itself
        # a class.
        # TODO: getattr doesn't return by default members
        # from the metaclass, because handling various cases
        # of methods accessible from the metaclass itself
        # and/or subclasses only is too complicated for little to
        # no benefit.
        metaclass = owner.metaclass() or owner.implicit_metaclass()
        try:
            if metaclass and metaclass.getattr(attrname):
                return False
        except NotFoundError:
            pass
    return True
Exemplo n.º 3
0
def _emit_no_member(node, owner, owner_name, ignored_mixins):
    """Try to see if no-member should be emitted for the given owner.

    The following cases are ignored:

        * the owner is a function and it has decorators.
        * the owner is an instance and it has __getattr__, __getattribute__ implemented
        * the module is explicitly ignored from no-member checks
        * the owner is a class and the name can be found in its metaclass.
        * The access node is protected by an except handler, which handles
          AttributeError, Exception or bare except.
    """
    if node_ignores_exception(node, AttributeError):
        return False
    # skip None anyway
    if isinstance(owner, astroid.Const) and owner.value is None:
        return False
    if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
        return False
    if ignored_mixins and owner_name[-5:].lower() == 'mixin':
        return False
    if isinstance(owner, astroid.FunctionDef) and owner.decorators:
        return False
    if isinstance(owner, astroid.Instance):
        if owner.has_dynamic_getattr() or not has_known_bases(owner):
            return False
    if isinstance(owner, objects.Super):
        # Verify if we are dealing with an invalid Super object.
        # If it is invalid, then there's no point in checking that
        # it has the required attribute. Also, don't fail if the
        # MRO is invalid.
        try:
            owner.super_mro()
        except (exceptions.MroError, exceptions.SuperError):
            return False
        if not all(map(has_known_bases, owner.type.mro())):
            return False
    return True
Exemplo n.º 4
0
def _emit_no_member(node, owner, owner_name, ignored_mixins):
    """Try to see if no-member should be emitted for the given owner.

    The following cases are ignored:

        * the owner is a function and it has decorators.
        * the owner is an instance and it has __getattr__, __getattribute__ implemented
        * the module is explicitly ignored from no-member checks
        * the owner is a class and the name can be found in its metaclass.
        * The access node is protected by an except handler, which handles
          AttributeError, Exception or bare except.
    """
    if node_ignores_exception(node, AttributeError):
        return False
    # skip None anyway
    if isinstance(owner, astroid.Const) and owner.value is None:
        return False
    if is_super(owner) or getattr(owner, "type", None) == "metaclass":
        return False
    if ignored_mixins and owner_name[-5:].lower() == "mixin":
        return False
    if isinstance(owner, astroid.FunctionDef) and owner.decorators:
        return False
    if isinstance(owner, astroid.Instance):
        if owner.has_dynamic_getattr() or not has_known_bases(owner):
            return False
    if isinstance(owner, objects.Super):
        # Verify if we are dealing with an invalid Super object.
        # If it is invalid, then there's no point in checking that
        # it has the required attribute. Also, don't fail if the
        # MRO is invalid.
        try:
            owner.super_mro()
        except (exceptions.MroError, exceptions.SuperError):
            return False
        if not all(map(has_known_bases, owner.type.mro())):
            return False
    return True
Exemplo n.º 5
0
    def visit_getattr(self, node):
        """check that the accessed attribute exists

        to avoid to much false positives for now, we'll consider the code as
        correct if a single of the inferred nodes has the accessed attribute.

        function/method, super call and metaclasses are ignored
        """
        # generated_members may containt regular expressions
        # (surrounded by quote `"` and followed by a comma `,`)
        # REQUEST,aq_parent,"[a-zA-Z]+_set{1,2}"' =>
        # ('REQUEST', 'aq_parent', '[a-zA-Z]+_set{1,2}')
        if isinstance(self.config.generated_members, str):
            gen = shlex.shlex(self.config.generated_members)
            gen.whitespace += ','
            gen.wordchars += '[]-+'
            self.config.generated_members = tuple(tok.strip('"') for tok in gen)
        for pattern in self.config.generated_members:
            # attribute is marked as generated, stop here
            if re.match(pattern, node.attrname):
                return
        try:
            infered = list(node.expr.infer())
        except InferenceError:
            return
        # list of (node, nodename) which are missing the attribute
        missingattr = set()
        ignoremim = self.config.ignore_mixin_members
        inference_failure = False
        for owner in infered:
            # skip yes object
            if owner is YES:
                inference_failure = True
                continue
            # skip None anyway
            if isinstance(owner, astroid.Const) and owner.value is None:
                continue
            # XXX "super" / metaclass call
            if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
                continue
            name = getattr(owner, 'name', 'None')
            if name in self.config.ignored_classes:
                continue
            if ignoremim and name[-5:].lower() == 'mixin':
                continue
            try:
                if not [n for n in owner.getattr(node.attrname)
                        if not isinstance(n.statement(), astroid.AugAssign)]:
                    missingattr.add((owner, name))
                    continue
            except AttributeError:
                # XXX method / function
                continue
            except NotFoundError:
                if isinstance(owner, astroid.Function) and owner.decorators:
                    continue
                if isinstance(owner, Instance) and owner.has_dynamic_getattr():
                    continue
                # explicit skipping of module member access
                if owner.root().name in self.config.ignored_modules:
                    continue
                missingattr.add((owner, name))
                continue
            # stop on the first found
            break
        else:
            # we have not found any node with the attributes, display the
            # message for infered nodes
            done = set()
            for owner, name in missingattr:
                if isinstance(owner, Instance):
                    actual = owner._proxied
                else:
                    actual = owner
                if actual in done:
                    continue
                done.add(actual)
                if inference_failure:
                    msgid = 'maybe-no-member'
                else:
                    msgid = 'no-member'
                self.add_message(msgid, node=node,
                                 args=(owner.display_type(), name,
                                       node.attrname))
Exemplo n.º 6
0
    def visit_getattr(self, node):
        """check that the accessed attribute exists

        to avoid to much false positives for now, we'll consider the code as
        correct if a single of the infered nodes has the accessed attribute.

        function/method, super call and metaclasses are ignored
        """
        if node.attrname in self.config.generated_members:
            # attribute is marked as generated, stop here
            return
        try:
            infered = list(node.expr.infer())
        except InferenceError:
            return
        # list of (node, nodename) which are missing the attribute
        missingattr = set()
        ignoremim = self.config.ignore_mixin_members
        inference_failure = False
        for owner in infered:
            # skip yes object
            if owner is YES:
                inference_failure = True
                continue
            # skip None anyway
            if isinstance(owner, astng.Const) and owner.value is None:
                continue
            # XXX "super" / metaclass call
            if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
                continue
            name = getattr(owner, 'name', 'None')
            if name in self.config.ignored_classes:
                continue
            if ignoremim and name[-5:].lower() == 'mixin':
                continue
            try:
                if not [n for n in owner.getattr(node.attrname)
                        if not isinstance(n.statement(), astng.AugAssign)]:
                    missingattr.add((owner, name))
                    continue
            except AttributeError:
                # XXX method / function
                continue
            except NotFoundError:
                if isinstance(owner, Instance) and owner.has_dynamic_getattr():
                    continue
                # explicit skipping of optparse'Values class
                if owner.name == 'Values' and \
                       owner.root().name in ('optik', 'optparse'):
                    continue
                missingattr.add((owner, name))
                continue
            # stop on the first found
            break
        else:
            # we have not found any node with the attributes, display the
            # message for infered nodes
            done = set()
            for owner, name in missingattr:
                if isinstance(owner, Instance):
                    actual = owner._proxied
                else:
                    actual = owner
                if actual in done:
                    continue
                done.add(actual)
                if inference_failure:
                    msgid = 'E1103'
                else:
                    msgid = 'E1101'
                self.add_message(msgid, node=node,
                                 args=(display_type(owner), name,
                                       node.attrname))
Exemplo n.º 7
0
    def visit_getattr(self, node):
        """check that the accessed attribute exists

        to avoid to much false positives for now, we'll consider the code as
        correct if a single of the inferred nodes has the accessed attribute.

        function/method, super call and metaclasses are ignored
        """
        if node.attrname in self.generated_members:
            # attribute is marked as generated, stop here
            return
        try:
            infered = list(node.expr.infer())
        except InferenceError:
            return
        # list of (node, nodename) which are missing the attribute
        missingattr = set()
        ignoremim = self.config.ignore_mixin_members
        inference_failure = False
        for owner in infered:
            # skip yes object
            if owner is YES:
                inference_failure = True
                continue
            # skip None anyway
            if isinstance(owner, astng.Const) and owner.value is None:
                continue
            # XXX "super" / metaclass call
            if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
                continue
            name = getattr(owner, 'name', 'None')
            if name in self.config.ignored_classes:
                continue
            if ignoremim and name[-5:].lower() == 'mixin':
                continue
            try:
                if not [n for n in owner.getattr(node.attrname)
                        if not isinstance(n.statement(), astng.AugAssign)]:
                    missingattr.add((owner, name))
                    continue
            except AttributeError:
                # XXX method / function
                continue
            except NotFoundError:
                if isinstance(owner, Instance) and owner.has_dynamic_getattr():
                    continue
                # explicit skipping of optparse'Values class
                if owner.name == 'Values' and owner.root().name == 'optparse':
                    continue
                missingattr.add((owner, name))
                continue
            # stop on the first found
            break
        else:
            # we have not found any node with the attributes, display the
            # message for infered nodes
            done = set()
            for owner, name in missingattr:
                if isinstance(owner, Instance):
                    actual = owner._proxied
                else:
                    actual = owner
                if actual in done:
                    continue
                done.add(actual)
                if inference_failure:
                    msgid = 'E1103'
                else:
                    msgid = 'E1101'
                self.add_message(msgid, node=node,
                                 args=(owner.display_type(), name,
                                       node.attrname))
Exemplo n.º 8
0
    def visit_getattr(self, node):
        """check that the accessed attribute exists

        to avoid to much false positives for now, we'll consider the code as
        correct if a single of the inferred nodes has the accessed attribute.

        function/method, super call and metaclasses are ignored
        """
        # generated_members may containt regular expressions
        # (surrounded by quote `"` and followed by a comma `,`)
        # REQUEST,aq_parent,"[a-zA-Z]+_set{1,2}"' =>
        # ('REQUEST', 'aq_parent', '[a-zA-Z]+_set{1,2}')
        if isinstance(self.config.generated_members, str):
            gen = shlex.shlex(self.config.generated_members)
            gen.whitespace += ","
            gen.wordchars += "[]-+"
            self.config.generated_members = tuple(tok.strip('"') for tok in gen)
        for pattern in self.config.generated_members:
            # attribute is marked as generated, stop here
            if re.match(pattern, node.attrname):
                return
        try:
            infered = list(node.expr.infer())
        except InferenceError:
            return
        # list of (node, nodename) which are missing the attribute
        missingattr = set()
        ignoremim = self.config.ignore_mixin_members
        inference_failure = False
        for owner in infered:
            # skip yes object
            if owner is YES:
                inference_failure = True
                continue
            # skip None anyway
            if isinstance(owner, astroid.Const) and owner.value is None:
                continue
            # XXX "super" / metaclass call
            if is_super(owner) or getattr(owner, "type", None) == "metaclass":
                continue
            name = getattr(owner, "name", "None")
            if name in self.config.ignored_classes:
                continue
            if ignoremim and name[-5:].lower() == "mixin":
                continue
            try:
                if not [n for n in owner.getattr(node.attrname) if not isinstance(n.statement(), astroid.AugAssign)]:
                    missingattr.add((owner, name))
                    continue
            except AttributeError:
                # XXX method / function
                continue
            except NotFoundError:
                if isinstance(owner, astroid.Function) and owner.decorators:
                    continue
                if isinstance(owner, Instance) and owner.has_dynamic_getattr():
                    continue
                # explicit skipping of module member access
                if owner.root().name in self.config.ignored_modules:
                    continue
                if isinstance(owner, astroid.Class):
                    # Look up in the metaclass only if the owner is itself
                    # a class.
                    # TODO: getattr doesn't return by default members
                    # from the metaclass, because handling various cases
                    # of methods accessible from the metaclass itself
                    # and/or subclasses only is too complicated for little to
                    # no benefit.
                    metaclass = owner.metaclass()
                    try:
                        if metaclass and metaclass.getattr(node.attrname):
                            continue
                    except NotFoundError:
                        pass
                missingattr.add((owner, name))
                continue
            # stop on the first found
            break
        else:
            # we have not found any node with the attributes, display the
            # message for infered nodes
            done = set()
            for owner, name in missingattr:
                if isinstance(owner, Instance):
                    actual = owner._proxied
                else:
                    actual = owner
                if actual in done:
                    continue
                done.add(actual)
                confidence = INFERENCE if not inference_failure else INFERENCE_FAILURE
                self.add_message(
                    "no-member", node=node, args=(owner.display_type(), name, node.attrname), confidence=confidence
                )