from typing import Any
from typing import List


def _get_method_children(expr: Any) -> List[Any]:
    """Recursively get potential "child" snippets of a snippet method

    This method recursively retrieves a list of expressions within
    a method that may represent calls to other snippets. This is
    necessary because tests that cover the parent snippet should
    also be considered to (recursively) cover any snippets called
    by the parent snippet itself.

    Args:
        expr (ast.AST): a Python expression object

    Returns:
        List[ast.AST]: a list of potential child snippet methods

    """
    results = []

    if hasattr(expr, 'id'):
        results.append(expr.id)  # Base case

    if hasattr(expr, 'body') and isinstance(expr.body, list):
        for sub_expr in expr.body:
            results += _get_method_children(sub_expr)

    if hasattr(expr, 'orelse') and isinstance(expr.orelse, list):
        for sub_expr in expr.orelse:
            results += _get_method_children(sub_expr)

    if hasattr(expr, 'value'):
        results += _get_method_children(expr.value)

    if hasattr(expr, 'func'):
        func_list = expr.func
        if not isinstance(func_list, list):
            # Not all func values are lists!
            func_list = [func_list]

        for func in func_list:
            results += _get_method_children(func)
            if hasattr(func, 'args'):
                for arg in func.args:
                    results += _get_method_children(arg)

    return results