human
Complete this python program:
def copy(source, destination, ignores=None):
assistant
#Here is the Python program you requested.

    """Recursively copy source into destination.
    If source is a file, destination has to be a file as well.
    The function is able to copy either files or directories.
    :param source: the source file or directory
    :param destination: the destination file or directory
    :param ignores: either None, or a list of glob patterns;
    files matching those patterns will _not_ be copied.
    """
    def walk_error(err):
        logger.warning(u'While    copying    %s:    %s:    %s', source_, err.filename, err.strerror)
    source_ = os.path.abspath(os.path.expanduser(source))
    destination_ = os.path.abspath(os.path.expanduser(destination))
    if (ignores is None):
        ignores = []
    if any((fnmatch.fnmatch(os.path.basename(source), ignore) for ignore in ignores)):
        logger.info(u'Not    copying    %s    due    to    ignores', source_)
        return
    if os.path.isfile(source_):
        dst_dir = os.path.dirname(destination_)
        if (not os.path.exists(dst_dir)):
            logger.info(u'Creating    directory    %s', dst_dir)
            os.makedirs(dst_dir)
        logger.info(u'Copying    %s    to    %s', source_, destination_)
        copy_file_metadata(source_, destination_)
    elif os.path.isdir(source_):
        if (not os.path.exists(destination_)):
            logger.info(u'Creating    directory    %s', destination_)
            os.makedirs(destination_)
        if (not os.path.isdir(destination_)):
            logger.warning(u'Cannot    copy    %s    (a    directory)    to    %s    (a    file)', source_, destination_)
            return
        for (src_dir, subdirs, others) in os.walk(source_):
            dst_dir = os.path.join(destination_, os.path.relpath(src_dir, source_))
            subdirs[:] = (s for s in subdirs if (not any((fnmatch.fnmatch(s, i) for i in ignores))))
            others[:] = (o for o in others if (not any((fnmatch.fnmatch(o, i) for i in ignores))))
            if (not os.path.isdir(dst_dir)):
                logger.info(u'Creating    directory    %s', dst_dir)
                os.mkdir(dst_dir)
            for o in others:
                src_path = os.path.join(src_dir, o)
                dst_path = os.path.join(dst_dir, o)
                if os.path.isfile(src_path):
                    logger.info(u'Copying    %s    to    %s', src_path, dst_path)
                    copy_file_metadata(src_path, dst_path)
                else:
              ...