'Uploads a new appversion with the given config and files to the server.
Args:
paths: An iterator that yields the relative paths of the files to upload.
openfunc: A function that takes a path and returns a file-like object.
Returns:
An appinfo.AppInfoSummary if one was returned from the server, None
otherwise.'

def DoUpload(self, paths, openfunc):

    start_time_usec = self.logging_context.GetCurrentTimeUsec()
    logging.info('Reading    app    configuration.')
    StatusUpdate(('\nStarting    update    of    %s' % self.Describe()), self.error_fh)
    path = ''
    try:
        self.resource_limits = GetResourceLimits(self.logging_context, self.error_fh)
        self._AddFilesThatAreSmallEnough(paths, openfunc)
    except KeyboardInterrupt:
        logging.info('User    interrupted.    Aborting.')
        raise
    except EnvironmentError as e:
        if self._IsExceptionClientDeployLoggable(e):
            self.logging_context.LogClientDeploy(self.config.runtime, start_time_usec, False)
        logging.error("An    error    occurred    processing    file    '%s':    %s.    Aborting.", path, e)
        raise
    try:
        missing_files = self.Begin()
        self._UploadMissingFiles(missing_files, openfunc)
        if (self.config.derived_file_type and (appinfo.PYTHON_PRECOMPILED in self.config.derived_file_type)):
            try:
                self.Precompile()
            except urllib2.HTTPError as e:
                ErrorUpdate(('Error    %d:    ---    begin    server    output    ---\n%s\n---    end    server    output    ---' % (e.code, e.read().rstrip('\n'))))
                if ((e.code == 422) or (self.config.GetEffectiveRuntime() == 'go')):
                    raise
                print >>self.error_fh, 'Precompilation    failed.    Your    app    can    still    serve    but    may    have    reduced    startup    performance.    You    can    retry    the    update    later    to    retry    the    precompilation    step.'
        app_summary = self.Commit()
        StatusUpdate(('Completed    update    of    %s' % self.Describe()), self.error_fh)
        self.logging_context.LogClientDeploy(self.config.runtime, start_time_usec, True)
    except BaseException as e:
        try:
            self._LogDoUploadException(e)
            self.Rollback()
        finally:
            if self._IsExceptionClientDeployLoggable(e):
                self.logging_context.LogClientDeploy(self.config.runtime, start_time_usec, False)
        raise
    logging.info('Done!')
    return app_summary
