Safer way to 'execute' python code to get a simple value
    :param line:
    :param version_token:
    :return:

def find_by_ast(line, version_token="__version__"):  # type: (str,str) -> Optional[str]
    """
    Safer way to 'execute' python code to get a simple value
    :param line:
    :param version_token:
    :return:
    """
    if not line:
        return ""
    # clean up line.
    simplified_line = simplify_line(line)

    if simplified_line.startswith(version_token):
        try:
            tree = ast.parse(simplified_line)  # type: Any
            if hasattr(tree.body[0].value, "s"):
                return unicode(tree.body[0].value.s)
            if hasattr(tree.body[0].value, "elts"):
                version_parts = []
                for elt in tree.body[0].value.elts:
                    if hasattr(elt, "n"):
                        version_parts.append(unicode(elt.n))
                    else:
                        version_parts.append(unicode(elt.s))
                return ".".join(version_parts)
            if hasattr(tree.body[0].value, "n"):
                return unicode(tree.body[0].value.n)
            # print(tree)
        except Exception:
            # raise
            return None

    return None