def _is_exempt_from_public_methods(node: astroid.ClassDef) -> bool: """Check if a class is exempt from too-few-public-methods""" # If it's a typing.Namedtuple or an Enum for ancestor in node.ancestors(): if ancestor.name == "Enum" and ancestor.root().name == "enum": return True if ancestor.qname() == TYPING_NAMEDTUPLE: return True # Or if it's a dataclass if not node.decorators: return False root_locals = set(node.root().locals) for decorator in node.decorators.nodes: if isinstance(decorator, astroid.Call): decorator = decorator.func if not isinstance(decorator, (astroid.Name, astroid.Attribute)): continue if isinstance(decorator, astroid.Name): name = decorator.name else: name = decorator.attrname if name in DATACLASSES_DECORATORS and ( root_locals.intersection(DATACLASSES_DECORATORS) or DATACLASS_IMPORT in root_locals): return True return False
def overrides_a_method(class_node: astroid.ClassDef, name: str) -> bool: """return True if <name> is a method overridden from an ancestor""" for ancestor in class_node.ancestors(): if name in ancestor and isinstance(ancestor[name], astroid.FunctionDef): return True return False
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(): if astroid.helpers.is_subtype(ancestor, parent): return True return False
def class_is_abstract(node: astroid.ClassDef) -> bool: """return true if the given class node should be considered as an abstract class """ # Only check for explicit metaclass=ABCMeta on this specific class meta = node.declared_metaclass() if meta is not None: if meta.name == "ABCMeta" and meta.root().name in ABC_MODULES: return True for ancestor in node.ancestors(): if ancestor.name == "ABC" and ancestor.root().name in ABC_MODULES: # abc.ABC inheritance return True for method in node.methods(): if method.parent.frame() is node: if method.is_abstract(pass_is_abstract=False): return True return False
def _is_typing_namedtuple(node: astroid.ClassDef) -> bool: """Check if a class node is a typing.NamedTuple class""" for base in node.ancestors(): if base.qname() == TYPING_NAMEDTUPLE: return True return False