import ast


def names_in_ptree(ptree):
    """
    Return a set of all of the Name strings in ptree

    Useful for finding the names of symbols defined via
    assignment in expressions, particulary tuples, which
    may be nested arbitrarily deeply.

    Skips NameConstants, because these values can't be
    overridden by assignment (or at least they really
    shouldn't be).
    """

    names = set()
    if not ptree:
        return names

    for node in ast.walk(ptree):
        if isinstance(node, ast.Name):
            names.add(node.id)

    return names