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 )
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
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)
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)
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)
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
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_
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)
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)