Esempio n. 1
0
    def visit_return(self, node):
        if not utils.returns_something(node):
            return

        func_node = node.frame()
        if not isinstance(func_node, astroid.FunctionDef):
            return

        doc = utils.docstringify(
            func_node.doc, self.config.default_docstring_type,
        )
        if not doc.is_valid() and self.config.accept_no_return_doc:
            return

        is_property = checker_utils.decorated_with_property(func_node)

        if not (doc.has_returns() or
                (doc.has_property_returns() and is_property)):
            self.add_message(
                'missing-return-doc',
                node=func_node
            )

        if func_node.returns:
            return

        if not (doc.has_rtype() or
                (doc.has_property_type() and is_property)):
            self.add_message(
                'missing-return-type-doc',
                node=func_node
            )
Esempio n. 2
0
def _is_attribute_property(name, klass):
    """ Check if the given attribute *name* is a property
    in the given *klass*.

    It will look for `property` calls or for functions
    with the given name, decorated by `property` or `property`
    subclasses.
    Returns ``True`` if the name is a property in the given klass,
    ``False`` otherwise.
    """

    try:
        attributes = klass.getattr(name)
    except astroid.NotFoundError:
        return False
    property_name = "{0}.property".format(BUILTINS)
    for attr in attributes:
        try:
            infered = next(attr.infer())
        except astroid.InferenceError:
            continue
        if (isinstance(infered, astroid.Function) and
                decorated_with_property(infered)):
            return True
        if infered.pytype() == property_name:
            return True
    return False
Esempio n. 3
0
 def get_methods(self, node):
     """return visible methods"""
     methods = [
         m for m in node.values()
         if isinstance(m, astroid.FunctionDef)
         and not decorated_with_property(m)
         and self.show_attr(m.name)
     ]
     return sorted(methods, key=lambda n: n.name)
Esempio n. 4
0
 def get_attrs(self, node):
     """return visible attributes, possibly with class name"""
     attrs = []
     properties = [
         (n, m) for n, m in node.items()
         if isinstance(m, astroid.FunctionDef)
         and decorated_with_property(m)
     ]
     for node_name, ass_nodes in list(node.instance_attrs_type.items()) + \
                                 list(node.locals_type.items()) + properties:
         if not self.show_attr(node_name):
             continue
         names = self.class_names(ass_nodes)
         if names:
             node_name = "%s : %s" % (node_name, ", ".join(names))
         attrs.append(node_name)
     return sorted(attrs)
Esempio n. 5
0
    def leave_functiondef(self, node):
        """on method node, check if this method couldn't be a function

        ignore class, static and abstract methods, initializer,
        methods overridden from a parent class.
        """
        if node.is_method():
            if node.args.args is not None:
                self._first_attrs.pop()
            if not self.linter.is_message_enabled('no-self-use'):
                return
            class_node = node.parent.frame()
            if (self._meth_could_be_func and node.type == 'method'
                    and node.name not in PYMETHODS
                    and not (node.is_abstract() or
                             overrides_a_method(class_node, node.name) or
                             decorated_with_property(node) or
                             (six.PY3 and _has_bare_super_call(node)))):
                self.add_message('no-self-use', node=node)
Esempio n. 6
0
    def _check_uninferable_callfunc(self, node):
        """
        Check that the given uninferable CallFunc node does not
        call an actual function.
        """
        if not isinstance(node.func, astroid.Attribute):
            return

        # Look for properties. First, obtain
        # the lhs of the Getattr node and search the attribute
        # there. If that attribute is a property or a subclass of properties,
        # then most likely it's not callable.

        # TODO: since astroid doesn't understand descriptors very well
        # we will not handle them here, right now.

        expr = node.func.expr
        klass = safe_infer(expr)
        if (klass is None or klass is astroid.YES or
                not isinstance(klass, astroid.Instance)):
            return

        try:
            attrs = klass._proxied.getattr(node.func.attrname)
        except exceptions.NotFoundError:
            return

        for attr in attrs:
            if attr is astroid.YES:
                continue
            if not isinstance(attr, astroid.FunctionDef):
                continue

            # Decorated, see if it is decorated with a property.
            # Also, check the returns and see if they are callable.
            if decorated_with_property(attr):
                if all(return_node.callable()
                       for return_node in attr.infer_call_result(node)):
                    continue
                else:
                    self.add_message('not-callable', node=node,
                                     args=node.func.as_string())
                    break
Esempio n. 7
0
def get_setters_property(node):
    """Get the property node for the given setter node.

    :param node: The node to get the property for.
    :type node: astroid.FunctionDef

    :rtype: astroid.FunctionDef or None
    :returns: The node relating to the property of the given setter node,
        or None if one could not be found.
    """
    property_ = None

    property_name = get_setters_property_name(node)
    class_node = utils.node_frame_class(node)
    if property_name and class_node:
        class_attrs = class_node.getattr(node.name)
        for attr in class_attrs:
            if utils.decorated_with_property(attr):
                property_ = attr
                break

    return property_
Esempio n. 8
0
def get_setters_property(node):
    """Get the property node for the given setter node.

    :param node: The node to get the property for.
    :type node: astroid.FunctionDef

    :rtype: astroid.FunctionDef or None
    :returns: The node relating to the property of the given setter node,
        or None if one could not be found.
    """
    property_ = None

    property_name = get_setters_property_name(node)
    class_node = utils.node_frame_class(node)
    if property_name and class_node:
        class_attrs = class_node.getattr(node.name)
        for attr in class_attrs:
            if utils.decorated_with_property(attr):
                property_ = attr
                break

    return property_
Esempio n. 9
0
    def visit_return(self, node):
        if not utils.returns_something(node):
            return

        func_node = node.frame()
        if not isinstance(func_node, astroid.FunctionDef):
            return

        doc = utils.docstringify(func_node.doc, self.config.default_docstring_type)
        if not doc.is_valid() and self.config.accept_no_return_doc:
            return

        is_property = checker_utils.decorated_with_property(func_node)

        if not (doc.has_returns() or (doc.has_property_returns() and is_property)):
            self.add_message("missing-return-doc", node=func_node)

        if func_node.returns:
            return

        if not (doc.has_rtype() or (doc.has_property_type() and is_property)):
            self.add_message("missing-return-type-doc", node=func_node)
Esempio n. 10
0
    def _check_uninferable_callfunc(self, node):
        """
        Check that the given uninferable CallFunc node does not
        call an actual function.
        """
        if not isinstance(node.func, astroid.Getattr):
            return

        # Look for properties. First, obtain
        # the lhs of the Getattr node and search the attribute
        # there. If that attribute is a property or a subclass of properties,
        # then most likely it's not callable.

        # TODO: since astroid doesn't understand descriptors very well
        # we will not handle them here, right now.

        expr = node.func.expr
        klass = safe_infer(expr)
        if (klass is None or klass is astroid.YES or
                not isinstance(klass, astroid.Instance)):
            return

        try:
            attrs = klass._proxied.getattr(node.func.attrname)
        except astroid.NotFoundError:
            return

        for attr in attrs:
            if attr is astroid.YES:
                continue
            if not isinstance(attr, astroid.Function):
                continue

            # Decorated, see if it is decorated with a property
            if decorated_with_property(attr):
                self.add_message('not-callable', node=node,
                                 args=node.func.as_string())
                break
 def visit_functiondef(self, node):
     """triggered when an import statement is seen"""
     if isinstance(node, astroid.FunctionDef) and decorated_with_property(node):
         self.add_message('no-properties', node=node)