pylint/checkers/utils.py
def unimplemented_abstract_methods(
    node: astroid.node_classes.NodeNG, is_abstract_cb: astroid.FunctionDef = None
) -> Dict[str, astroid.node_classes.NodeNG]:
    """
    Get the unimplemented abstract methods for the given *node*.

    A method can be considered abstract if the callback *is_abstract_cb*
    returns a ``True`` value. The check defaults to verifying that
    a method is decorated with abstract methods.
    The function will work only for new-style classes. For old-style
    classes, it will simply return an empty dictionary.
    For the rest of them, it will return a dictionary of abstract method
    names and their inferred objects.
    """
    if is_abstract_cb is None:
        is_abstract_cb = partial(decorated_with, qnames=ABC_METHODS)
    visited = {}  # type: Dict[str, astroid.node_classes.NodeNG]
    try:
        mro = reversed(node.mro())
    except NotImplementedError:
        # Old style class, it will not have a mro.
        return {}
    except astroid.ResolveError:
        # Probably inconsistent hierarchy, don'try
        # to figure this out here.
        return {}
    for ancestor in mro:
        for obj in ancestor.values():
            infered = obj
            if isinstance(obj, astroid.AssignName):
                infered = safe_infer(obj)
                if not infered:
                    # Might be an abstract function,
                    # but since we don't have enough information
                    # in order to take this decision, we're taking
                    # the *safe* decision instead.
                    if obj.name in visited:
                        del visited[obj.name]
                    continue
                if not isinstance(infered, astroid.FunctionDef):
                    if obj.name in visited:
                        del visited[obj.name]
            if isinstance(infered, astroid.FunctionDef):
                # It's critical to use the original name,
                # since after inferring, an object can be something
                # else than expected, as in the case of the
                # following assignment.
                #
                # class A:
                #     def keys(self): pass
                #     __iter__ = keys
                abstract = is_abstract_cb(infered)
                if abstract:
                    visited[obj.name] = infered
                elif not abstract and obj.name in visited:
                    del visited[obj.name]
    return visited
def unimplemented_abstract_methods(
    node: astroid.node_classes.NodeNG, is_abstract_cb: astroid.FunctionDef = None
) -> Dict[str, astroid.node_classes.NodeNG]:
    """
    Get the unimplemented abstract methods for the given *node*.

    A method can be considered abstract if the callback *is_abstract_cb*
    returns a ``True`` value. The check defaults to verifying that
    a method is decorated with abstract methods.
    The function will work only for new-style classes. For old-style
    classes, it will simply return an empty dictionary.
    For the rest of them, it will return a dictionary of abstract method
    names and their inferred objects.
    """
    if is_abstract_cb is None:
        is_abstract_cb = partial(decorated_with, qnames=ABC_METHODS)
    visited = {}  # type: Dict[str, astroid.node_classes.NodeNG]
    try:
        mro = reversed(node.mro())
    except NotImplementedError:
        # Old style class, it will not have a mro.
        return {}
    except astroid.ResolveError:
        # Probably inconsistent hierarchy, don'try
        # to figure this out here.
        return {}
    for ancestor in mro:
        for obj in ancestor.values():
            infered = obj
            if isinstance(obj, astroid.AssignName):
                infered = safe_infer(obj)
                if not infered:
                    # Might be an abstract function,
                    # but since we don't have enough information
                    # in order to take this decision, we're taking
                    # the *safe* decision instead.
                    if obj.name in visited:
                        del visited[obj.name]
                    continue
                if not isinstance(infered, astroid.FunctionDef):
                    if obj.name in visited:
                        del visited[obj.name]
            if isinstance(infered, astroid.FunctionDef):
                # It's critical to use the original name,
                # since after inferring, an object can be something
                # else than expected, as in the case of the
                # following assignment.
                #
                # class A:
                #     def keys(self): pass
                #     __iter__ = keys
                abstract = is_abstract_cb(infered)
                if abstract:
                    visited[obj.name] = infered
                elif not abstract and obj.name in visited:
                    del visited[obj.name]
    return visited
def unimplemented_abstract_methods ( node : astroid . node_classes . NodeNG , is_abstract_cb : astroid . FunctionDef = None ) -> Dict [ str , astroid . node_classes . NodeNG ] : if is_abstract_cb is None : is_abstract_cb = partial ( decorated_with , qnames = ABC_METHODS ) visited = { } # type: Dict[str, astroid.node_classes.NodeNG] try : mro = reversed ( node . mro ( ) ) except NotImplementedError : # Old style class, it will not have a mro. return { } except astroid . ResolveError : # Probably inconsistent hierarchy, don'try # to figure this out here. return { } for ancestor in mro : for obj in ancestor . values ( ) : infered = obj if isinstance ( obj , astroid . AssignName ) : infered = safe_infer ( obj ) if not infered : # Might be an abstract function, # but since we don't have enough information # in order to take this decision, we're taking # the *safe* decision instead. if obj . name in visited : del visited [ obj . name ] continue if not isinstance ( infered , astroid . FunctionDef ) : if obj . name in visited : del visited [ obj . name ] if isinstance ( infered , astroid . FunctionDef ) : # It's critical to use the original name, # since after inferring, an object can be something # else than expected, as in the case of the # following assignment. # # class A: #     def keys(self): pass #     __iter__ = keys abstract = is_abstract_cb ( infered ) if abstract : visited [ obj . name ] = infered elif not abstract and obj . name in visited : del visited [ obj . name ] return visited
Get the unimplemented abstract methods for the given *node*.

    A method can be considered abstract if the callback *is_abstract_cb*
    returns a ``True`` value. The check defaults to verifying that
    a method is decorated with abstract methods.
    The function will work only for new-style classes. For old-style
    classes, it will simply return an empty dictionary.
    For the rest of them, it will return a dictionary of abstract method
    names and their inferred objects.
Get the unimplemented abstract methods for the given * node * .