def get_cl_statuses(changes, fine_grained, max_processes=None):
    "Returns a blocking iterable of (cl, status) for given branches.\n\n  If fine_grained is true, this will fetch CL statuses from the server.\n  Otherwise, simply indicate if there's a matching url for the given branches.\n\n  If max_processes is specified, it is used as the maximum number of processes\n  to spawn to fetch CL status from the server. Otherwise 1 process per branch is\n  spawned.\n\n  See GetStatus() for a list of possible statuses.\n  "
    upload.verbosity = 0
    if fine_grained:
        if changes:
            fetch = (lambda cl: (cl, cl.GetStatus()))
            (yield fetch(changes[0]))
            if (not changes):
                return
            changes_to_fetch = changes[1:]
            pool = ThreadPool((min(max_processes, len(changes_to_fetch)) if (max_processes is not None) else len(changes_to_fetch)))
            fetched_cls = set()
            it = pool.imap_unordered(fetch, changes_to_fetch).__iter__()
            while True:
                try:
                    row = it.next(timeout=5)
                except multiprocessing.TimeoutError:
                    break
                fetched_cls.add(row[0])
                (yield row)
            for cl in (set(changes_to_fetch) - fetched_cls):
                (yield (cl, 'error'))
    else:
        for cl in changes:
            (yield (cl, ('waiting' if cl.GetIssueURL() else 'error')))
Returns a blocking iterable of (cl, status) for given branches.

If fine_grained is true, this will fetch CL statuses from the server.
Otherwise, simply indicate if there's a matching url for the given branches.

If max_processes is specified, it is used as the maximum number of processes
to spawn to fetch CL status from the server. Otherwise 1 process per branch is
spawned.

See GetStatus() for a list of possible statuses.
def get_cl_statuses(changes, fine_grained, max_processes=None):
    "Returns a blocking iterable of (cl, status) for given branches.\n\n  If fine_grained is true, this will fetch CL statuses from the server.\n  Otherwise, simply indicate if there's a matching url for the given branches.\n\n  If max_processes is specified, it is used as the maximum number of processes\n  to spawn to fetch CL status from the server. Otherwise 1 process per branch is\n  spawned.\n\n  See GetStatus() for a list of possible statuses.\n  "
    upload.verbosity = 0
    if fine_grained:
        if changes:
            fetch = (lambda cl: (cl, cl.GetStatus()))
            (yield fetch(changes[0]))
            if (not changes):
                return
            changes_to_fetch = changes[1:]
            pool = ThreadPool((min(max_processes, len(changes_to_fetch)) if (max_processes is not None) else len(changes_to_fetch)))
            fetched_cls = set()
            it = pool.imap_unordered(fetch, changes_to_fetch).__iter__()
            while True:
                try:
                    row = it.next(timeout=5)
                except multiprocessing.TimeoutError:
                    break
                fetched_cls.add(row[0])
                (yield row)
            for cl in (set(changes_to_fetch) - fetched_cls):
                (yield (cl, 'error'))
    else:
        for cl in changes:
            (yield (cl, ('waiting' if cl.GetIssueURL() else 'error')))