def _find_sources(im, target, sources, polarity):
    """Get the subset of source nodes with paths to the target.

    Given a target, a list of sources, and a path polarity, perform a
    breadth-first search upstream from the target to determine whether any of
    the queried sources have paths to the target with the appropriate polarity.
    For efficiency, does not return the full path, but identifies the upstream
    sources and the length of the path.

    Parameters
    ----------
    im : networkx.MultiDiGraph
        Graph containing the influence map.
    target : str
        The node (rule name) in the influence map to start looking upstream for
        marching sources.
    sources : list of str
        The nodes (rules) corresponding to the subject or upstream influence
        being checked.
    polarity : int
        Required polarity of the path between source and target.

    Returns
    -------
    generator of (source, polarity, path_length)
        Yields tuples of source node (string), polarity (int) and path length
        (int). If there are no paths to any of the given source nodes, the
        generator isignempty.
    """
    # First, create a list of visited nodes
    # Adapted from
    # networkx.algorithms.traversal.breadth_first_search.bfs_edges
    visited = set([(target, 1)])
    # Generate list of predecessor nodes with a sign updated according to the
    # sign of the target node
    target_tuple = (target, 1)
    # The queue holds tuples of "parents" (in this case downstream nodes) and
    # their "children" (in this case their upstream influencers)
    queue = deque([(target_tuple, _get_signed_predecessors(im, target, 1), 0)])
    while queue:
        parent, children, path_length = queue[0]
        try:
            # Get the next child in the list
            (child, sign) = next(children)
            # Is this child one of the source nodes we're looking for? If so,
            # yield it along with path length.
            if (sources is None or child in sources) and sign == polarity:
                logger.debug("Found path to %s from %s with desired sign %s "
                             "with length %d" %
                             (target, child, polarity, path_length+1))
                yield (child, sign, path_length+1)
            # Check this child against the visited list. If we haven't visited
            # it already (accounting for the path to the node), then add it
            # to the queue.
            if (child, sign) not in visited:
                visited.add((child, sign))
                queue.append(((child, sign),
                              _get_signed_predecessors(im, child, sign),
                              path_length + 1))
        # Once we've finished iterating over the children of the current node,
        # pop the node off and go to the next one in the queue
        except StopIteration:
            queue.popleft()
    # There was no path; this will produce an empty generator
    return