[yum] update to latest HEAD Weird old bugs fixed for new createrepo code. Add --assumeno and an easter egg

James Antill james at fedoraproject.org
Fri Jul 15 20:05:43 UTC 2011


commit e73665edfa64b64b952d68692b6ff674f4d5b474
Author: James Antill <james at and.org>
Date:   Fri Jul 15 16:05:25 2011 -0400

    update to latest HEAD
    Weird old bugs fixed for new createrepo code.
    Add --assumeno and an easter egg! Also allow remove to use alwaysprompt.
    Fix \r appearing on serial console etc. BZ 720088.
    Fix umask on mkdir() as well as open. BZ 719467.
    Fix traceback when enabling/disabling repos. in GUI.

 yum-HEAD.patch | 2680 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 yum.spec       |   10 +-
 2 files changed, 2688 insertions(+), 2 deletions(-)
---
diff --git a/yum-HEAD.patch b/yum-HEAD.patch
index d0b6a7e..022ec69 100644
--- a/yum-HEAD.patch
+++ b/yum-HEAD.patch
@@ -1,3 +1,2018 @@
+diff --git a/cli.py b/cli.py
+old mode 100644
+new mode 100755
+index 6056d38..43c0e1d
+--- a/cli.py
++++ b/cli.py
+@@ -25,7 +25,7 @@ import sys
+ import time
+ import random
+ import logging
+-from optparse import OptionParser,OptionGroup
++from optparse import OptionParser,OptionGroup,SUPPRESS_HELP
+ import rpm
+ 
+ from weakref import proxy as weakref
+@@ -51,23 +51,24 @@ from yum.i18n import to_unicode, to_utf8
+ from yum.packages import parsePackages
+ 
+ def sigquit(signum, frame):
+-    """ SIGQUIT handler for the yum cli. """
++    """SIGQUIT handler for the yum cli.  This function will print an
++    error message and exit the program.
++    
++    :param signum: unused
++    :param frame: unused
++    """
+     print >> sys.stderr, "Quit signal sent - exiting immediately"
+     sys.exit(1)
+ 
+ class CliError(yum.Errors.YumBaseError):
+-
+-    """
+-    Command line interface related Exception.
+-    """
++    """Command line interface related Exception."""
+ 
+     def __init__(self, args=''):
+         yum.Errors.YumBaseError.__init__(self)
+         self.args = args
+ 
+ class YumBaseCli(yum.YumBase, output.YumOutput):
+-    """This is the base class for yum cli.
+-       Inherits from yum.YumBase and output.YumOutput """
++    """This is the base class for yum cli."""
+        
+     def __init__(self):
+         # handle sigquit early on
+@@ -106,15 +107,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         self.registerCommand(yumcommands.LoadTransactionCommand())
+ 
+     def registerCommand(self, command):
++        """Register a :class:`yumcommands.YumCommand` so that it can be called by
++        any of the names returned by its
++        :func:`yumcommands.YumCommand.getNames` method.
++        
++        :param command: the :class:`yumcommands.YumCommand` to register
++        """
+         for name in command.getNames():
+             if name in self.yum_cli_commands:
+                 raise yum.Errors.ConfigError(_('Command "%s" already defined') % name)
+             self.yum_cli_commands[name] = command
+             
+     def doRepoSetup(self, thisrepo=None, dosack=1):
+-        """grabs the repomd.xml for each enabled repository 
+-           and sets up the basics of the repository"""
+-        
++        """Grab the repomd.xml for each enabled and set up the basics
++        of the repository.
++
++        :param thisrepo: the repository to set up
++        :param dosack: whether to get the repo sack
++        """
+         if self._repos and thisrepo is None:
+             return self._repos
+             
+@@ -183,10 +193,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         
+         
+     def getOptionsConfig(self, args):
+-        """parses command line arguments, takes cli args:
+-        sets up self.conf and self.cmds as well as logger objects 
+-        in base instance"""
+-       
++        """Parse command line arguments, and set up :attr:`self.conf` and
++        :attr:`self.cmds`, as well as logger objects in base instance.
++
++        :param args: a list of command line arguments
++        """
+         self.optparser = YumOptionParser(base=self, usage=self._makeUsage())
+         
+         # Parse only command line options that affect basic yum setup
+@@ -318,9 +329,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         time.sleep(sleeptime)
+         
+     def parseCommands(self):
+-        """reads self.cmds and parses them out to make sure that the requested 
+-        base command + argument makes any sense at all""" 
+-
++        """Read :attr:`self.cmds` and parse them out to make sure that
++        the requested base command and argument makes any sense at
++        all.  This function will also set :attr:`self.basecmd` and
++        :attr:`self.extcmds`.
++        """
+         self.verbose_logger.debug('Yum Version: %s', yum.__version__)
+         self.verbose_logger.log(yum.logginglevels.DEBUG_4,
+                                 'COMMAND: %s', self.cmdstring)
+@@ -365,7 +378,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         self.history.write_addon_data('shell-cmds', data)
+ 
+     def doShell(self):
+-        """do a shell-like interface for yum commands"""
++        """Run a shell-like interface for yum commands.
++
++        :return: a tuple containing the shell result number, and the
++           shell result messages
++        """
+ 
+         yumshell = shell.YumShell(base=self)
+ 
+@@ -382,8 +399,12 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return yumshell.result, yumshell.resultmsgs
+ 
+     def errorSummary(self, errstring):
+-        """ parse the error string for 'interesting' errors which can
+-            be grouped, such as disk space issues """
++        """Parse the error string for 'interesting' errors which can
++        be grouped, such as disk space issues.
++
++        :param errstring: the error string
++        :return: a string containing a summary of the errors
++        """
+         summary = ''
+         # do disk space report first
+         p = re.compile('needs (\d+)MB on the (\S+) filesystem')
+@@ -408,16 +429,17 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+ 
+ 
+     def doCommands(self):
+-        """
+-        Calls the base command passes the extended commands/args out to be
+-        parsed (most notably package globs).
+-        
+-        Returns a numeric result code and an optional string
+-           - 0 = we're done, exit
+-           - 1 = we've errored, exit with error string
+-           - 2 = we've got work yet to do, onto the next stage
+-        """
+-        
++        """Call the base command, and pass it the extended commands or
++           arguments.
++
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """       
+         # at this point we know the args are valid - we don't know their meaning
+         # but we know we're not being sent garbage
+         
+@@ -440,9 +462,13 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return self.yum_cli_commands[self.basecmd].doCommand(self, self.basecmd, self.extcmds)
+ 
+     def doTransaction(self):
+-        """takes care of package downloading, checking, user confirmation and actually
+-           RUNNING the transaction"""
+-    
++        """Take care of package downloading, checking, user
++        confirmation and actually running the transaction.
++
++        :return: a numeric return code, and optionally a list of
++           errors.  A negative return code indicates that errors
++           occurred in the pre-transaction checks
++        """
+         # just make sure there's not, well, nothing to do
+         if len(self.tsInfo) == 0:
+             self.verbose_logger.info(_('Trying to run the transaction but nothing to do. Exiting.'))
+@@ -453,7 +479,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         lsts = self.listTransaction()
+         if self.verbose_logger.isEnabledFor(yum.logginglevels.INFO_1):
+             self.verbose_logger.log(yum.logginglevels.INFO_1, lsts)
+-        elif not self.conf.assumeyes:
++        elif self.conf.assumeno or not self.conf.assumeyes:
+             #  If we are in quiet, and assumeyes isn't on we want to output
+             # at least the transaction list anyway.
+             self.logger.warn(lsts)
+@@ -491,7 +517,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         
+         # confirm with user
+         if self._promptWanted():
+-            if not self.userconfirm():
++            if self.conf.assumeno or not self.userconfirm():
+                 self.verbose_logger.info(_('Exiting on user Command'))
+                 return -1
+ 
+@@ -609,12 +635,14 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return resultobject.return_code
+         
+     def gpgsigcheck(self, pkgs):
+-        '''Perform GPG signature verification on the given packages, installing
+-        keys if possible
++        """Perform GPG signature verification on the given packages,
++        installing keys if possible.
+ 
+-        Returns non-zero if execution should stop (user abort).
+-        Will raise YumBaseError if there's a problem
+-        '''
++        :param pkgs: a list of package objects to verify the GPG
++           signatures of
++        :return: non-zero if execution should stop due to an error
++        :raises: Will raise :class:`YumBaseError` if there's a problem
++        """
+         for po in pkgs:
+             result, errmsg = self.sigCheckPkg(po)
+ 
+@@ -623,7 +651,8 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+                 continue            
+ 
+             elif result == 1:
+-                if not sys.stdin.isatty() and not self.conf.assumeyes:
++                ay = self.conf.assumeyes and not self.conf.assumeno
++                if not sys.stdin.isatty() and not ay:
+                     raise yum.Errors.YumBaseError, \
+                             _('Refusing to automatically import keys when running ' \
+                             'unattended.\nUse "-y" to override.')
+@@ -692,11 +721,22 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+             self.verbose_logger.log(yum.logginglevels.INFO_2, msg)
+ 
+     def installPkgs(self, userlist):
+-        """Attempts to take the user specified list of packages/wildcards
+-           and install them, or if they are installed, update them to a newer
+-           version. If a complete version number if specified, attempt to 
+-           upgrade (or downgrade if they have been removed) them to the
+-           specified version"""
++        """Attempt to take the user specified list of packages or
++        wildcards and install them, or if they are installed, update
++        them to a newer version. If a complete version number is
++        specified, attempt to upgrade (or downgrade if they have been
++        removed) them to the specified version.
++
++        :param userlist: a list of names or wildcards specifying
++           packages to install
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         # get the list of available packages
+         # iterate over the user's list
+         # add packages to Transaction holding class if they match.
+@@ -732,9 +772,27 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, [_('Nothing to do')]
+         
+     def updatePkgs(self, userlist, quiet=0, update_to=False):
+-        """take user commands and populate transaction wrapper with 
+-           packages to be updated"""
+-        
++        """Take user commands and populate transaction wrapper with
++        packages to be updated.
++
++        :param userlist: a list of names or wildcards specifying
++           packages to update.  If *userlist* is an empty list, yum
++           will perform a global update
++        :param quiet: unused
++        :param update_to: if *update_to* is True, the update will only
++           be run if it will update the given package to the given
++           version.  For example, if the package foo-1-2 is installed,
++           updatePkgs(["foo-1-2], update_to=False) will work
++           identically to updatePkgs(["foo"]), but
++           updatePkgs(["foo-1-2"], update_to=True) will do nothing
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         # if there is no userlist, then do global update below
+         # this is probably 90% of the calls
+         # if there is a userlist then it's for updating pkgs, not obsoleting
+@@ -770,9 +828,24 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+     #  Note that we aren't in __init__ yet for a couple of reasons, but we 
+     # probably will get there for 3.2.28.
+     def distroSyncPkgs(self, userlist):
+-        """ This does either upgrade/downgrade, depending on if the latest
+-            installed version is older or newer. We allow "selection" but not
+-            local packages (use tmprepo, or something). """
++        """Upgrade or downgrade packages to match the latest versions
++        available in the enabled repositories.
++
++        :param userlist: list of names or wildcards specifying
++           packages to synchronize with the repositories.  If the
++           first string in *userlist* is "full", packages will also be
++           reinstalled if their checksums do not match the checksums
++           in the repositories.  If *userlist* is an empty list or
++           only contains "full", every installed package will be
++           synchronized
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+ 
+         level = 'diff'
+         if userlist and userlist[0] in ('full', 'diff', 'different'):
+@@ -866,9 +939,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+             return 0, [_('No Packages marked for Distribution Synchronization')]
+ 
+     def erasePkgs(self, userlist):
+-        """take user commands and populate a transaction wrapper with packages
+-           to be erased/removed"""
+-        
++        """Take user commands and populate a transaction wrapper with
++        packages to be erased.
++
++        :param userlist: a list of names or wildcards specifying
++           packages to erase
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         oldcount = len(self.tsInfo)
+ 
+         all_rms = []
+@@ -884,9 +967,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+             return 0, [_('No Packages marked for removal')]
+     
+     def downgradePkgs(self, userlist):
+-        """Attempts to take the user specified list of packages/wildcards
+-           and downgrade them. If a complete version number if specified,
+-           attempt to downgrade them to the specified version"""
++        """Attempt to take the user specified list of packages or
++        wildcards and downgrade them. If a complete version number if
++        specified, attempt to downgrade them to the specified version
++
++        :param userlist: a list of names or wildcards specifying
++           packages to downgrade
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+ 
+         oldcount = len(self.tsInfo)
+         
+@@ -911,8 +1005,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, [_('Nothing to do')]
+         
+     def reinstallPkgs(self, userlist):
+-        """Attempts to take the user specified list of packages/wildcards
+-           and reinstall them. """
++        """Attempt to take the user specified list of packages or
++        wildcards and reinstall them.
++
++        :param userlist: a list of names or wildcards specifying
++           packages to reinstall
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+ 
+         oldcount = len(self.tsInfo)
+ 
+@@ -946,9 +1051,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, [_('Nothing to do')]
+ 
+     def localInstall(self, filelist, updateonly=0):
+-        """handles installs/updates of rpms provided on the filesystem in a 
+-           local dir (ie: not from a repo)"""
+-           
++        """Install or update rpms provided on the file system in a
++        local directory (i.e. not from a repository).
++
++        :param filelist: a list of names specifying local rpms
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """           
+         # read in each package into a YumLocalPackage Object
+         # append it to self.localPackages
+         # check if it can be installed or updated based on nevra versus rpmdb
+@@ -972,20 +1086,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, [_('Nothing to do')]
+ 
+     def returnPkgLists(self, extcmds, installed_available=False):
+-        """Returns packages lists based on arguments on the cli.returns a 
+-           GenericHolder instance with the following lists defined:
+-           available = list of packageObjects
+-           installed = list of packageObjects
+-           updates = tuples of packageObjects (updating, installed)
+-           extras = list of packageObjects
+-           obsoletes = tuples of packageObjects (obsoleting, installed)
+-           recent = list of packageObjects
+-
+-           installed_available = that the available package list is present
+-                                 as .hidden_available when doing any of:
+-                                 all/available/installed
+-           """
+-        
++        """Return a :class:`yum.misc.GenericHolder` object containing
++        lists of package objects that match the given names or wildcards.
++
++        :param extcmds: a list of names or wildcards specifying
++           packages to list
++        :param installed_available: whether the available package list
++           is present as .hidden_available when doing all, available,
++           or installed
++
++        :return: a :class:`yum.misc.GenericHolder` instance with the
++           following lists defined::
++
++             available = list of packageObjects
++             installed = list of packageObjects
++             updates = tuples of packageObjects (updating, installed)
++             extras = list of packageObjects
++             obsoletes = tuples of packageObjects (obsoleting, installed)
++             recent = list of packageObjects
++        """
+         special = ['available', 'installed', 'all', 'extras', 'updates', 'recent',
+                    'obsoletes']
+         
+@@ -1017,8 +1136,25 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return ypl
+ 
+     def search(self, args):
+-        """cli wrapper method for module search function, searches simple
+-           text tags in a package object"""
++        """Search for simple text tags in a package object. This is a
++        cli wrapper method for the module search function.
++
++        :param args: list of names or wildcards to search for.
++           Normally this method will begin by searching the package
++           names and summaries, and will only search urls and
++           descriptions if that fails.  However, if the first string
++           in *args* is "all", this method will always search
++           everything
++        :return: a tuple where the first item is an exit code, and
++           the second item is a generator if the search is a
++           successful, and a list of error messages otherwise
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         
+         # call the yum module search function with lists of tags to search
+         # and what to search for
+@@ -1108,9 +1244,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, matching
+ 
+     def deplist(self, args):
+-        """cli wrapper method for findDeps method takes a list of packages and 
+-            returns a formatted deplist for that package"""
++        """Print out a formatted list of dependencies for a list of
++        packages.  This is a cli wrapper method for
++        :class:`yum.YumBase.findDeps`.
+ 
++        :param args: a list of names or wildcards specifying packages
++           that should have their dependenices printed
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         pkgs = []
+         for arg in args:
+             if (arg.endswith('.rpm') and (yum.misc.re_remote_url(arg) or
+@@ -1131,10 +1278,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, []
+ 
+     def provides(self, args):
+-        """use the provides methods in the rpmdb and pkgsack to produce a list 
+-           of items matching the provides strings. This is a cli wrapper to the 
+-           module"""
+-        
++        """Print out a list of packages that provide the given file or
++        feature.  This a cli wrapper to the provides methods in the
++        rpmdb and pkgsack.
++
++        :param args: the name of a file or feature to search for
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         old_sdup = self.conf.showdupesfromrepos
+         # For output, as searchPackageProvides() is always in showdups mode
+         self.conf.showdupesfromrepos = True
+@@ -1163,8 +1319,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, []
+     
+     def resolveDepCli(self, args):
+-        """returns a package (one per user arg) that provide the supplied arg"""
+-        
++        """Print information about a package that provides the given
++        dependency.  Only one package will be printed per dependency.
++
++        :param args: a list of strings specifying dependencies to
++           search for
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         for arg in args:
+             try:
+                 pkg = self.returnPackageByDep(arg)
+@@ -1177,6 +1344,34 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, []
+     
+     def cleanCli(self, userlist):
++        """Remove data from the yum cache directory.  What data is
++        removed depends on the options supplied by the user.
++
++        :param userlist: a list of options.  The following are valid
++           options::
++
++             expire-cache = Eliminate the local data saying when the
++               metadata and mirror lists were downloaded for each
++               repository.
++             packages = Eliminate any cached packages
++             headers = Eliminate the header files, which old versions
++               of yum used for dependency resolution
++             metadata = Eliminate all of the files which yum uses to
++               determine the remote availability of packages
++             dbcache = Eliminate the sqlite cache used for faster
++               access to metadata
++             rpmdb = Eliminate any cached datat from the local rpmdb
++             plugins = Tell any enabled plugins to eliminate their
++               cached data
++             all = do all of the above
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         hdrcode = pkgcode = xmlcode = dbcode = expccode = 0
+         pkgresults = hdrresults = xmlresults = dbresults = expcresults = []
+         msg = self.fmtKeyValFill(_('Cleaning repos: '), 
+@@ -1228,7 +1423,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return code, []
+ 
+     def returnGroupLists(self, userlist):
++        """Print out a list of groups that match the given names or
++        wildcards.
++
++        :param extcmds: a list of names or wildcards specifying
++           groups to list
++        :return: (exit_code, [ errors ])
+ 
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage        
++        """
+         uservisible=1
+             
+         if len(userlist) > 0:
+@@ -1283,7 +1490,20 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, [_('Done')]
+ 
+     def returnGroupSummary(self, userlist):
++        """Print a summary of the groups that match the given names or
++        wildcards.
++
++        :param userlist: a list of names or wildcards specifying the
++           groups to summarise. If *userlist* is an empty list, all
++           installed and available packages will be summarised
++        :return: (exit_code, [ errors ])
+ 
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         uservisible=1
+             
+         if len(userlist) > 0:
+@@ -1327,7 +1547,19 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, [_('Done')]
+     
+     def returnGroupInfo(self, userlist):
+-        """returns complete information on a list of groups"""
++        """Print complete information about the groups that match the
++        given names or wildcards.
++
++        :param userlist: a list of names or wildcards specifying the
++           groups to print information about
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         for strng in userlist:
+             group_matched = False
+             for group in self.comps.return_groups(strng):
+@@ -1340,8 +1572,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return 0, []
+         
+     def installGroups(self, grouplist):
+-        """for each group requested do 'selectGroup' on them."""
+-        
++        """Mark the packages in the given groups for installation.
++
++        :param grouplist: a list of names or wildcards specifying
++           groups to be installed
++        :return: (exit_code, [ errors ])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         pkgs_used = []
+         
+         for group_string in grouplist:
+@@ -1368,8 +1610,18 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+             return 2, [P_('%d package to Install', '%d packages to Install', len(pkgs_used)) % len(pkgs_used)]
+ 
+     def removeGroups(self, grouplist):
+-        """Remove only packages of the named group(s). Do not recurse."""
++        """Mark the packages in the given groups for removal.
++
++        :param grouplist: a list of names or wildcards specifying
++           groups to be removed
++        :return: (exit_code, [ errors ])
+ 
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++            2 = we've got work yet to do, onto the next stage
++        """
+         pkgs_used = []
+         for group_string in grouplist:
+             try:
+@@ -1389,7 +1641,7 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+ 
+     def _promptWanted(self):
+         # shortcut for the always-off/always-on options
+-        if self.conf.assumeyes:
++        if self.conf.assumeyes and not self.conf.assumeno:
+             return False
+         if self.conf.alwaysprompt:
+             return True
+@@ -1400,7 +1652,6 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         #  package wasn't explictly given on the command line
+         for txmbr in self.tsInfo.getMembers():
+             if txmbr.isDep or \
+-                   txmbr.ts_state == 'e' or \
+                    txmbr.name not in self.extcmds:
+                 return True
+         
+@@ -1408,11 +1659,11 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return False
+ 
+     def usage(self):
+-        ''' Print out command line usage '''
++        """Print out an explanation of command line usage."""
+         sys.stdout.write(self.optparser.format_help())
+ 
+     def shellUsage(self):
+-        ''' Print out the shell usage '''
++        """Print out an explanation of the shell usage."""
+         sys.stdout.write(self.optparser.get_usage())
+     
+     def _installable(self, pkg, ematch=False):
+@@ -1468,9 +1719,9 @@ class YumBaseCli(yum.YumBase, output.YumOutput):
+         return False
+ 
+ class YumOptionParser(OptionParser):
+-    '''Subclass that makes some minor tweaks to make OptionParser do things the
++    """Subclass that makes some minor tweaks to make OptionParser do things the
+     "yum way".
+-    '''
++    """
+ 
+     def __init__(self,base, **kwargs):
+         # check if this is called with a utils=True/False parameter
+@@ -1488,13 +1739,23 @@ class YumOptionParser(OptionParser):
+         self._addYumBasicOptions()
+ 
+     def error(self, msg):
+-        '''This method is overridden so that error output goes to logger. '''
++        """Output an error message, and exit the program.  This method
++        is overridden so that error output goes to the logger.
++
++        :param msg: the error message to output
++        """
+         self.print_usage()
+         self.logger.critical(_("Command line error: %s"), msg)
+         sys.exit(1)
+ 
+     def firstParse(self,args):
+-        # Parse only command line options that affect basic yum setup
++        """Parse only command line options that affect basic yum
++        setup.
++
++        :param args: a list of command line options to parse
++        :return: a dictionary containing the values of command line
++           options
++        """
+         try:
+             args = _filtercmdline(
+                         ('--noplugins','--version','-q', '-v', "--quiet", "--verbose"), 
+@@ -1521,7 +1782,15 @@ class YumOptionParser(OptionParser):
+         return ret
+         
+     def setupYumConfig(self, args=None):
+-        # Now parse the command line for real
++        """Parse command line options.
++
++        :param args: the command line arguments entered by the user
++        :return: (opts, cmds)  opts is a dictionary containing
++           the values of command line options.  cmds is a list of the
++           command line arguments that were not parsed as options.
++           For example, if args is ["install", "foo", "--verbose"],
++           cmds will be ["install", "foo"].
++        """
+         if not args:
+             (opts, cmds) = self.parse_args()
+         else:
+@@ -1536,7 +1805,9 @@ class YumOptionParser(OptionParser):
+                 
+             # Handle remaining options
+             if opts.assumeyes:
+-                self.base.conf.assumeyes =1
++                self.base.conf.assumeyes = 1
++            if opts.assumeno:
++                self.base.conf.assumeno  = 1
+ 
+             #  Instead of going cache-only for a non-root user, try to use a
+             # user writable cachedir. If that fails fall back to cache-only.
+@@ -1640,6 +1911,14 @@ class YumOptionParser(OptionParser):
+         sys.exit(1)
+ 
+     def getRoot(self,opts):
++        """Return the root location to use for the yum operation.
++        This location can be changed by using the --installroot
++        option.
++
++        :param opts: a dictionary containing the values of the command
++           line options
++        :return: a string representing the root location
++        """
+         self._checkAbsInstallRoot(opts)
+         # If the conf file is inside the  installroot - use that.
+         # otherwise look for it in the normal root
+@@ -1713,6 +1992,10 @@ class YumOptionParser(OptionParser):
+                         help=_("verbose operation"))
+         group.add_option("-y", "--assumeyes", dest="assumeyes",
+                 action="store_true", help=_("answer yes for all questions"))
++        group.add_option("--assumeno", dest="assumeno",
++                action="store_true", help=_("answer no for all questions"))
++        group.add_option("--nodeps", dest="assumeno", # easter egg :)
++                action="store_true", help=SUPPRESS_HELP)
+         group.add_option("--version", action="store_true", 
+                 help=_("show Yum version and exit"))
+         group.add_option("--installroot", help=_("set install root"), 
+diff --git a/docs/yum.8 b/docs/yum.8
+index 1a8202a..ea18f34 100644
+--- a/docs/yum.8
++++ b/docs/yum.8
+@@ -401,6 +401,11 @@ Assume yes; assume that the answer to any question which would be asked
+ is yes\&.
+ .br
+ Configuration Option: \fBassumeyes\fP
++.IP "\fB\-\-assumeno\fP"
++Assume no; assume that the answer to any question which would be asked 
++is no\&. This option overrides assumeyes, but is still subject to alwaysprompt.
++.br
++Configuration Option: \fBassumeno\fP
+ .IP "\fB\-c, \-\-config=[config file]\fP" 
+ Specifies the config file location - can take HTTP and FTP URLs and local file
+ paths\&.
+diff --git a/docs/yum.conf.5 b/docs/yum.conf.5
+index 515aa73..bd86eea 100644
+--- a/docs/yum.conf.5
++++ b/docs/yum.conf.5
+@@ -114,15 +114,27 @@ are causing problems from the transaction.
+ Either `1' or `0'. Determines whether or not yum prompts for confirmation of
+ critical actions. Default is `0' (do prompt).
+ .br
+-Command-line option: \fB\-y\fP
++Command-line option: \fB\-y\fP \fB\--assumeyes\fP
++
++.IP
++\fBassumeno\fR
++Either `1' or `0'. If yum would prompt for confirmation of critical actions, 
++assume the user chose no. This is basically the same as doing "echo | yum ..."
++but is a bit more usable. This option overrides \fBassumeyes\fP, but is still
++subject to \fBalwaysprompt\fP.
++Default is `0' (do prompt).
++.br
++Command-line option: \fB\--assumeno\fP
+ 
+ .IP
+ \fBalwaysprompt\fR
+ Either `1' or `0'. Without this option, yum will not prompt for confirmation
+ when the list of packages to be installed exactly matches those given on the
+-command line. Unless \fBassumeyes\fR is enabled, it will still prompt for
+-package removal, or when additional packages need to be installed to fulfill
+-dependencies. Default is `1'.
++command line. Unless \fBassumeyes\fR is enabled, it will still prompt when
++additional packages need to be installed to fulfill dependencies. Note that
++older versions of yum would also always prompt for package removal, and that is
++no longer true.
++Default is `1'.
+ .br
+ 
+ .IP
+@@ -131,6 +143,7 @@ Either `1' or `0'. If enabled, then yum will be tolerant of errors on the
+ command line with regard to packages. For example: if you request to install
+ foo, bar and baz and baz is installed; yum won't error out complaining that baz
+ is already installed. Default to `0' (not tolerant).
++Note: This option currently does nothing.
+ .br
+ Command-line option: \fB\-t\fP
+ 
+diff --git a/etc/yum.bash b/etc/yum.bash
+index f1e06e8..7fd97ae 100644
+--- a/etc/yum.bash
++++ b/etc/yum.bash
+@@ -45,7 +45,7 @@ _yum_grouplist()
+ {
+     local IFS=$'\n'
+     # TODO: add -d 0 when http://yum.baseurl.org/ticket/29 is fixed
+-    COMPREPLY=( $( compgen -W "$( ${yum:-yum} -C grouplist $1 "$2*" \
++    COMPREPLY=( $( compgen -W "$( ${yum:-yum} -C grouplist $1 \
+         2>/dev/null | sed -ne 's/^[[:space:]]\{1,\}\(.\{1,\}\)/\1/p' )" \
+         -- "$2" ) )
+ }
+@@ -89,6 +89,16 @@ _yum_transactions()
+         sed -ne 's/^[[:space:]]*\([0-9]\{1,\}\).*/\1/p' )" -- "$cur" ) )
+ }
+ 
++_yum_atgroups()
++{
++    if [[ $1 == \@* ]]; then
++        _yum_grouplist "" "${1:1}"
++        COMPREPLY=( "${COMPREPLY[@]/#/@}" )
++        return 0
++    fi
++    return 1
++}
++
+ # arguments:
+ #   1 = current word to be completed
+ #   2 = previous word
+@@ -231,13 +241,15 @@ _yum()
+             ;;
+ 
+         downgrade|reinstall)
+-            _yum_binrpmfiles "$cur"
+-            _yum_list installed "$cur"
++            if ! _yum_atgroups "$cur" ; then
++                _yum_binrpmfiles "$cur"
++                _yum_list installed "$cur"
++            fi
+             return 0
+             ;;
+ 
+         erase|remove)
+-            _yum_list installed "$cur"
++            _yum_atgroups "$cur" || _yum_list installed "$cur"
+             return 0
+             ;;
+ 
+@@ -288,8 +300,10 @@ _yum()
+             ;;
+ 
+         install)
+-            _yum_binrpmfiles "$cur"
+-            _yum_list available "$cur"
++            if ! _yum_atgroups "$cur" ; then
++                _yum_binrpmfiles "$cur"
++                _yum_list available "$cur"
++            fi
+             return 0
+             ;;
+ 
+@@ -318,8 +332,10 @@ _yum()
+             ;;
+ 
+         update|upgrade)
+-            _yum_binrpmfiles "$cur"
+-            _yum_list updates "$cur"
++            if ! _yum_atgroups "$cur" ; then
++                _yum_binrpmfiles "$cur"
++                _yum_list updates "$cur"
++            fi
+             return 0
+             ;;
+         version)
+diff --git a/output.py b/output.py
+index b6aa277..9610232 100755
+--- a/output.py
++++ b/output.py
+@@ -1,6 +1,6 @@
+ #!/usr/bin/python -t
+ 
+-"""This handles actual output from the cli"""
++"""Handle actual output from the cli."""
+ 
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+@@ -60,17 +60,21 @@ def _term_width():
+ 
+ 
+ class YumTextMeter(TextMeter):
+-
+-    """
+-    Text progress bar output.
+-    """
++    """A class to display text progress bar output."""
+ 
+     def update(self, amount_read, now=None):
++        """Update the status of the text progress bar
++
++        :param amount_read: the amount of data, in bytes, that has been read
++        :param now: the current time in seconds since the epoch.  If
++           *now* is not given, the output of :func:`time.time()` will
++           be used.
++        """
+         checkSignals()
+         TextMeter.update(self, amount_read, now)
+ 
+ class YumTerm:
+-    """some terminal "UI" helpers based on curses"""
++    """A class to provide some terminal "UI" helpers based on curses."""
+ 
+     # From initial search for "terminfo and python" got:
+     # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116
+@@ -145,6 +149,17 @@ class YumTerm:
+         self.BG_COLOR = self.__ansi_forced_BG_COLOR
+ 
+     def reinit(self, term_stream=None, color='auto'):
++        """Reinitializes the :class:`YumTerm`.
++
++        :param term_stream:  the terminal stream that the
++           :class:`YumTerm` should be initialized to use.  If
++           *term_stream* is not given, :attr:`sys.stdout` is used.
++        :param color: when to colorize output.  Valid values are
++           'always', 'auto', and 'never'.  'always' will use ANSI codes
++           to always colorize output, 'auto' will decide whether do
++           colorize depending on the terminal, and 'never' will never
++           colorize.
++        """
+         self.__enabled = True
+         if not hasattr(urlgrabber.progress, 'terminal_width_cached'):
+             self.columns = 80
+@@ -255,6 +270,37 @@ class YumTerm:
+         return re.sub(r'\$<\d+>[/*]?', '', cap)
+ 
+     def sub(self, haystack, beg, end, needles, escape=None, ignore_case=False):
++        """Search the string *haystack* for all occurrences of any
++        string in the list *needles*.  Prefix each occurrence with
++        *beg*, and postfix each occurrence with *end*, then return the
++        modified string.  For example::
++           
++           >>> yt = YumTerm()
++           >>> yt.sub('spam and eggs', 'x', 'z', ['and'])
++           'spam xandz eggs'
++
++        This is particularly useful for emphasizing certain words
++        in output: for example, calling :func:`sub` with *beg* =
++        MODE['bold'] and *end* = MODE['normal'] will return a string
++        that when printed to the terminal will appear to be *haystack*
++        with each occurrence of the strings in *needles* in bold
++        face.  Note, however, that the :func:`sub_mode`,
++        :func:`sub_bold`, :func:`sub_fg`, and :func:`sub_bg` methods
++        provide convenient ways to access this same emphasizing functionality. 
++
++        :param haystack: the string to be modified
++        :param beg: the string to be prefixed onto matches
++        :param end: the string to be postfixed onto matches
++        :param needles: a list of strings to add the prefixes and
++           postfixes to
++        :param escape: a function that accepts a string and returns
++           the same string with problematic characters escaped.  By
++           default, :func:`re.escape` is used.
++        :param ignore_case: whether case should be ignored when
++           searching for matches
++        :return: *haystack* with *beg* prefixing, and *end*
++          postfixing, occurrences of the strings in *needles*
++        """
+         if not self.__enabled:
+             return haystack
+ 
+@@ -269,27 +315,106 @@ class YumTerm:
+             haystack = re.sub(pat, render, haystack)
+         return haystack
+     def sub_norm(self, haystack, beg, needles, **kwds):
++        """Search the string *haystack* for all occurrences of any
++        string in the list *needles*.  Prefix each occurrence with
++        *beg*, and postfix each occurrence with self.MODE['normal'],
++        then return the modified string.  If *beg* is an ANSI escape
++        code, such as given by self.MODE['bold'], this method will
++        return *haystack* with the formatting given by the code only
++        applied to the strings in *needles*.
++
++        :param haystack: the string to be modified
++        :param beg: the string to be prefixed onto matches
++        :param end: the string to be postfixed onto matches
++        :param needles: a list of strings to add the prefixes and
++           postfixes to
++        :return: *haystack* with *beg* prefixing, and self.MODE['normal']
++          postfixing, occurrences of the strings in *needles*
++        """
+         return self.sub(haystack, beg, self.MODE['normal'], needles, **kwds)
+ 
+     def sub_mode(self, haystack, mode, needles, **kwds):
++        """Search the string *haystack* for all occurrences of any
++        string in the list *needles*.  Prefix each occurrence with
++        self.MODE[*mode*], and postfix each occurrence with
++        self.MODE['normal'], then return the modified string.  This
++        will return a string that when printed to the terminal will
++        appear to be *haystack* with each occurrence of the strings in
++        *needles* in the given *mode*.
++
++        :param haystack: the string to be modified
++        :param mode: the mode to set the matches to be in.  Valid
++           values are given by self.MODE.keys().
++        :param needles: a list of strings to add the prefixes and
++           postfixes to
++        :return: *haystack* with self.MODE[*mode*] prefixing, and
++          self.MODE['normal'] postfixing, occurrences of the strings
++          in *needles*
++        """
+         return self.sub_norm(haystack, self.MODE[mode], needles, **kwds)
+ 
+     def sub_bold(self, haystack, needles, **kwds):
++        """Search the string *haystack* for all occurrences of any
++        string in the list *needles*.  Prefix each occurrence with
++        self.MODE['bold'], and postfix each occurrence with
++        self.MODE['normal'], then return the modified string.  This
++        will return a string that when printed to the terminal will
++        appear to be *haystack* with each occurrence of the strings in
++        *needles* in bold face.
++
++        :param haystack: the string to be modified
++        :param needles: a list of strings to add the prefixes and
++           postfixes to
++        :return: *haystack* with self.MODE['bold'] prefixing, and
++          self.MODE['normal'] postfixing, occurrences of the strings
++          in *needles*
++        """
+         return self.sub_mode(haystack, 'bold', needles, **kwds)
+     
+     def sub_fg(self, haystack, color, needles, **kwds):
++        """Search the string *haystack* for all occurrences of any
++        string in the list *needles*.  Prefix each occurrence with
++        self.FG_COLOR[*color*], and postfix each occurrence with
++        self.MODE['normal'], then return the modified string.  This
++        will return a string that when printed to the terminal will
++        appear to be *haystack* with each occurrence of the strings in
++        *needles* in the given color.
++
++        :param haystack: the string to be modified
++        :param color: the color to set the matches to be in.  Valid
++           values are given by self.FG_COLOR.keys().
++        :param needles: a list of strings to add the prefixes and
++           postfixes to
++        :return: *haystack* with self.FG_COLOR[*color*] prefixing, and
++          self.MODE['normal'] postfixing, occurrences of the strings
++          in *needles*
++        """
+         return self.sub_norm(haystack, self.FG_COLOR[color], needles, **kwds)
+ 
+     def sub_bg(self, haystack, color, needles, **kwds):
++        """Search the string *haystack* for all occurrences of any
++        string in the list *needles*.  Prefix each occurrence with
++        self.BG_COLOR[*color*], and postfix each occurrence with
++        self.MODE['normal'], then return the modified string.  This
++        will return a string that when printed to the terminal will
++        appear to be *haystack* with each occurrence of the strings in
++        *needles* highlighted in the given background color.
++
++        :param haystack: the string to be modified
++        :param color: the background color to set the matches to be in.  Valid
++           values are given by self.BG_COLOR.keys().
++        :param needles: a list of strings to add the prefixes and
++           postfixes to
++        :return: *haystack* with self.BG_COLOR[*color*] prefixing, and
++          self.MODE['normal'] postfixing, occurrences of the strings
++          in *needles*
++        """
+         return self.sub_norm(haystack, self.BG_COLOR[color], needles, **kwds)
+ 
+ 
+ 
+ class YumOutput:
+-
+-    """
+-    Main output class for the yum command line.
+-    """
++    """Main output class for the yum command line."""
+ 
+     def __init__(self):
+         self.logger = logging.getLogger("yum.cli")
+@@ -304,6 +429,12 @@ class YumOutput:
+ 
+     
+     def printtime(self):
++        """Return a string representing the current time in the form::
++
++           Mon dd hh:mm:ss
++
++        :return: a string representing the current time
++        """
+         months = [_('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'),
+                   _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')]
+         now = time.localtime(time.time())
+@@ -312,14 +443,27 @@ class YumOutput:
+         return ret
+          
+     def failureReport(self, errobj):
+-        """failure output for failovers from urlgrabber"""
+-        
++        """Perform failure output for failovers from urlgrabber
++
++        :param errobj: :class:`urlgrabber.grabber.CallbackObject`
++           containing information about the error
++        :raises: *errobj*.exception
++        """
+         self.logger.error('%s: %s', errobj.url, errobj.exception)
+         self.logger.error(_('Trying other mirror.'))
+         raise errobj.exception
+     
+         
+     def simpleProgressBar(self, current, total, name=None):
++        """Output the current status to the terminal using a simple
++        status bar.
++
++        :param current: a number representing the amount of work
++           already done
++        :param total: a number representing the total amount of work
++           to be done
++        :param name: a name to label the progress bar with
++        """
+         progressbar(current, total, name)
+ 
+     def _highlight(self, highlight):
+@@ -368,9 +512,29 @@ class YumOutput:
+ 
+     def calcColumns(self, data, columns=None, remainder_column=0,
+                     total_width=None, indent=''):
+-        """ Dynamically calculate the width of the fields in the data, data is
+-            of the format [column-number][field_length] = rows. """
+-
++        """Dynamically calculate the widths of the columns that the
++        fields in data should be placed into for output.
++        
++        :param data: a list of dictionaries that represent the data to
++           be output.  Each dictionary in the list corresponds to a
++           column of output. The keys of the dictionary are the
++           lengths of the items to be output, and the value associated
++           with a key is the number of items of that length.
++        :param columns: a list containing the minimum amount of space
++           that must be allocated for each row. This can be used to
++           ensure that there is space available in a column if, for
++           example, the actual lengths of the items being output
++           cannot be given in *data*
++        :param remainder_column: number of the column to receive a few
++           extra spaces that may remain after other allocation has
++           taken place
++        :param total_width: the total width of the output.
++           self.term.columns is used by default
++        :param indent: string that will be prefixed to a line of
++           output to create e.g. an indent
++        :return: a list of the widths of the columns that the fields
++           in data should be placed into for output
++        """
+         if total_width is None:
+             total_width = self.term.columns
+ 
+@@ -473,10 +637,20 @@ class YumOutput:
+         return (val, width, hibeg, hiend)
+ 
+     def fmtColumns(self, columns, msg=u'', end=u'', text_width=utf8_width):
+-        """ Return a string for columns of data, which can overflow.
+-            text_width parameter finds the width of columns, this defaults to
+-            utf8 but can be changed to len() if you know it'll be fine. """
+-
++        """Return a row of data formatted into a string for output.
++        Items can overflow their columns. 
++
++        :param columns: a list of tuples containing the data to
++           output.  Each tuple contains first the item to be output,
++           then the amount of space allocated for the column, and then
++           optionally a type of highlighting for the item
++        :param msg: a string to begin the line of output with
++        :param end: a string to end the line of output with
++        :param text_width: a function to find the width of the items
++           in the columns.  This defaults to utf8 but can be changed
++           to len() if you know it'll be fine
++        :return: a row of data formatted into a string for output
++        """
+         total_width = len(msg)
+         data = []
+         for col_data in columns[:-1]:
+@@ -513,8 +687,18 @@ class YumOutput:
+ 
+     def simpleList(self, pkg, ui_overflow=False, indent='', highlight=False,
+                    columns=None):
+-        """ Simple to use function to print a pkg as a line. """
+-
++        """Print a package as a line.
++
++        :param pkg: the package to be printed
++        :param ui_overflow: unused
++        :param indent: string to be prefixed onto the line to provide
++           e.g. an indent
++        :param highlight: highlighting options for the name of the
++           package
++        :param colums: tuple containing the space allocated for each
++           column of output.  The columns are the package name, version,
++           and repository
++        """
+         if columns is None:
+             columns = (-40, -22, -16) # Old default
+         ver = pkg.printVer()
+@@ -526,9 +710,19 @@ class YumOutput:
+ 
+     def simpleEnvraList(self, pkg, ui_overflow=False,
+                         indent='', highlight=False, columns=None):
+-        """ Simple to use function to print a pkg as a line, with the pkg
+-            itself in envra format so it can be pased to list/install/etc. """
+-
++        """Print a package as a line, with the package itself in envra
++        format so it can be passed to list/install/etc. 
++
++        :param pkg: the package to be printed
++        :param ui_overflow: unused
++        :param indent: string to be prefixed onto the line to provide
++           e.g. an indent
++        :param highlight: highlighting options for the name of the
++           package
++        :param colums: tuple containing the space allocated for each
++           column of output.  The columns the are the package envra and
++           repository
++        """
+         if columns is None:
+             columns = (-63, -16) # Old default
+         envra = '%s%s' % (indent, str(pkg))
+@@ -538,7 +732,13 @@ class YumOutput:
+         print self.fmtColumns(columns, text_width=len)
+ 
+     def fmtKeyValFill(self, key, val):
+-        """ Return a key value pair in the common two column output format. """
++        """Return a key value pair in the common two column output
++        format.
++
++        :param key: the key to be formatted
++        :param val: the value associated with *key*
++        :return: the key value pair formatted in two columns for output
++        """
+         val = to_str(val)
+         keylen = utf8_width(key)
+         cols = self.term.columns
+@@ -553,6 +753,15 @@ class YumOutput:
+         return ret
+     
+     def fmtSection(self, name, fill='='):
++        """Format and return a section header.  The format of the
++        header is a line with *name* centred, and *fill* repeated on
++        either side to fill an entire line on the terminal.
++
++        :param name: the name of the section
++        :param fill: the character to repeat on either side of *name*
++          to fill an entire line.  *fill* must be a single character.
++        :return: a string formatted to be a section header
++        """
+         name = to_str(name)
+         cols = self.term.columns - 2
+         name_len = utf8_width(name)
+@@ -577,6 +786,12 @@ class YumOutput:
+         return to_unicode(s)
+ 
+     def infoOutput(self, pkg, highlight=False):
++        """Print information about the given package.
++
++        :param pkg: the package to print information about 
++        :param hightlight: highlighting options for the name of the
++           package
++        """
+         (hibeg, hiend) = self._highlight(highlight)
+         print _("Name        : %s%s%s") % (hibeg, to_unicode(pkg.name), hiend)
+         print _("Arch        : %s") % to_unicode(pkg.arch)
+@@ -617,9 +832,22 @@ class YumOutput:
+         print ""
+     
+     def updatesObsoletesList(self, uotup, changetype, columns=None):
+-        """takes an updates or obsoletes tuple of pkgobjects and
+-           returns a simple printed string of the output and a string
+-           explaining the relationship between the tuple members"""
++        """Print a simple string that explains the relationship
++        between the members of an update or obsoletes tuple.
++
++        :param uotup: an update or obsoletes tuple.  The first member
++           is the new package, and the second member is the old
++           package
++        :param changetype: a string indicating what the change between
++           the packages is, e.g. 'updates' or 'obsoletes'
++        :param columns: a tuple containing information about how to
++           format the columns of output.  The absolute value of each
++           number in the tuple indicates how much space has been
++           allocated for the corresponding column.  If the number is
++           negative, the text in the column will be left justified,
++           and if it is positive, the text will be right justified.
++           The columns of output are the package name, version, and repository
++        """
+         (changePkg, instPkg) = uotup
+ 
+         if columns is not None:
+@@ -640,12 +868,44 @@ class YumOutput:
+ 
+     def listPkgs(self, lst, description, outputType, highlight_na={},
+                  columns=None, highlight_modes={}):
+-        """outputs based on whatever outputType is. Current options:
+-           'list' - simple pkg list
+-           'info' - similar to rpm -qi output
+-           ...also highlight_na can be passed, and we'll highlight
+-           pkgs with (names, arch) in that set."""
+-
++        """Prints information about the given list of packages.
++
++        :param lst: a list of packages to print information about
++        :param description: string describing what the list of
++           packages contains, e.g. 'Available Packages'
++        :param outputType: The type of information to be printed.
++           Current options::
++           
++              'list' - simple pkg list
++              'info' - similar to rpm -qi output
++        :param highlight_na: a dictionary containing information about
++              packages that should be highlighted in the output.  The
++              dictionary keys are (name, arch) tuples for the package,
++              and the associated values are the package objects
++              themselves.
++        :param columns: a tuple containing information about how to
++           format the columns of output.  The absolute value of each
++           number in the tuple indicates how much space has been
++           allocated for the corresponding column.  If the number is
++           negative, the text in the column will be left justified,
++           and if it is positive, the text will be right justified.
++           The columns of output are the package name, version, and
++           repository
++        :param highlight_modes: dictionary containing information
++              about to highlight the packages in *highlight_na*.
++              *highlight_modes* should contain the following keys::
++                 
++                 'not_in' - highlighting used for packages not in *highlight_na*
++                 '=' - highlighting used when the package versions are equal
++                 '<' - highlighting used when the package has a lower version number
++                 '>' - highlighting used when the package has a higher version number
++        :return: (exit_code, [errors])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++        """
+         if outputType in ['list', 'info']:
+             thingslisted = 0
+             if len(lst) > 0:
+@@ -679,8 +939,11 @@ class YumOutput:
+     
+         
+     def userconfirm(self):
+-        """gets a yes or no from the user, defaults to No"""
++        """Get a yes or no from the user, and default to No
+ 
++        :return: True if the user selects yes, and False if the user
++           selects no
++        """
+         yui = (to_unicode(_('y')), to_unicode(_('yes')))
+         nui = (to_unicode(_('n')), to_unicode(_('no')))
+         aui = (yui[0], yui[1], nui[0], nui[1])
+@@ -774,6 +1037,10 @@ class YumOutput:
+                                          columns=columns)
+     
+     def displayPkgsInGroups(self, group):
++        """Output information about the packages in a given group
++        
++        :param group: a Group object to output information about
++        """
+         print _('\nGroup: %s') % group.ui_name
+ 
+         verb = self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)
+@@ -807,8 +1074,11 @@ class YumOutput:
+                                            columns=columns)
+ 
+     def depListOutput(self, results):
+-        """take a list of findDeps results and 'pretty print' the output"""
+-        
++        """Format and output a list of findDeps results
++
++        :param results: a list of package dependency information as
++           returned by findDeps
++        """
+         verb = self.verbose_logger.isEnabledFor(logginglevels.DEBUG_3)
+         for pkg in sorted(results):
+             print _("package: %s") % pkg.compactPrint()
+@@ -832,7 +1102,18 @@ class YumOutput:
+                     print "   provider: %s" % po.compactPrint()
+ 
+     def format_number(self, number, SI=0, space=' '):
+-        """Turn numbers into human-readable metric-like numbers"""
++        """Return a human-readable metric-like string representation
++        of a number.
++
++        :param number: the number to be converted to a human-readable form
++        :param SI: If is 0, this function will use the convention
++           that 1 kilobyte = 1024 bytes, otherwise, the convention
++           that 1 kilobyte = 1000 bytes will be used
++        :param space: string that will be placed between the number
++           and the SI prefix
++        :return: a human-readable metric-like string representation of
++           *number*
++        """
+         symbols = [ ' ', # (none)
+                     'k', # kilo
+                     'M', # mega
+@@ -870,16 +1151,31 @@ class YumOutput:
+ 
+     @staticmethod
+     def format_time(seconds, use_hours=0):
++        """Return a human-readable string representation of a number
++        of seconds.  The string will show seconds, minutes, and
++        optionally hours.
++
++        :param seconds: the number of seconds to convert to a
++           human-readable form
++        :param use_hours: If use_hours is 0, the representation will
++           be in minutes and seconds. Otherwise, it will be in hours,
++           minutes, and seconds
++        :return: a human-readable string representation of *seconds*
++        """
+         return urlgrabber.progress.format_time(seconds, use_hours)
+ 
+     def matchcallback(self, po, values, matchfor=None, verbose=None,
+                       highlight=None):
+-        """ Output search/provides type callback matches. po is the pkg object,
+-            values are the things in the po that we've matched.
+-            If matchfor is passed, all the strings in that list will be
+-            highlighted within the output.
+-            verbose overrides logginglevel, if passed. """
+-
++        """Output search/provides type callback matches.
++
++        :param po: the package object that matched the search
++        :param values: the information associated with *po* that
++           matched the search
++        :param matchfor: a list of strings to be highlighted in the
++           output
++        :param verbose: whether to output extra verbose information
++        :param highlight: highlighting options for the highlighted matches
++        """
+         if self.conf.showdupesfromrepos:
+             msg = '%s : ' % po
+         else:
+@@ -935,10 +1231,23 @@ class YumOutput:
+         print '\n\n'
+ 
+     def matchcallback_verbose(self, po, values, matchfor=None):
++        """Output search/provides type callback matches.  This will
++        output more information than :func:`matchcallback`.
++
++        :param po: the package object that matched the search
++        :param values: the information associated with *po* that
++           matched the search
++        :param matchfor: a list of strings to be highlighted in the
++           output
++        """
+         return self.matchcallback(po, values, matchfor, verbose=True)
+         
+     def reportDownloadSize(self, packages, installonly=False):
+-        """Report the total download size for a set of packages"""
++        """Report the total download size for a set of packages
++        
++        :param packages: a list of package objects
++        :param installonly: whether the transaction consists only of installations
++        """
+         totsize = 0
+         locsize = 0
+         insize  = 0
+@@ -982,7 +1291,10 @@ class YumOutput:
+                                         self.format_number(insize))
+ 
+     def reportRemoveSize(self, packages):
+-        """Report the total size of packages being removed. """
++        """Report the total size of packages being removed.
++
++        :param packages: a list of package objects
++        """
+         totsize = 0
+         error = False
+         for pkg in packages:
+@@ -1002,8 +1314,9 @@ class YumOutput:
+                                     self.format_number(totsize))
+             
+     def listTransaction(self):
+-        """returns a string rep of the  transaction in an easy-to-read way."""
+-        
++        """Return a string representation of the transaction in an
++        easy-to-read format.
++        """
+         self.tsInfo.makelists(True, True)
+         pkglist_lines = []
+         data  = {'n' : {}, 'v' : {}, 'r' : {}}
+@@ -1115,6 +1428,12 @@ Transaction Summary
+         return ''.join(out)
+         
+     def postTransactionOutput(self):
++        """Returns a human-readable summary of the results of the
++        transaction.
++        
++        :return: a string containing a human-readable summary of the
++           results of the transaction
++        """
+         out = ''
+         
+         self.tsInfo.makelists()
+@@ -1179,9 +1498,9 @@ Transaction Summary
+         return out
+ 
+     def setupProgressCallbacks(self):
+-        """sets up the progress callbacks and various 
+-           output bars based on debug level"""
+-
++        """Set up the progress callbacks and various 
++           output bars based on debug level.
++        """
+         # if we're below 2 on the debug level we don't need to be outputting
+         # progress bars - this is hacky - I'm open to other options
+         # One of these is a download
+@@ -1216,10 +1535,12 @@ Transaction Summary
+         self.dsCallback = dscb
+     
+     def setupProgessCallbacks(self):
+-        # api purposes only to protect the typo
++        """This function is for API purposes only to protect the typo."""
+         self.setupProgressCallbacks()
+     
+     def setupKeyImportCallbacks(self):
++        """Set up callbacks to import and confirm gpg public keys."""
++
+         confirm_func = self._cli_confirm_gpg_key_import
+         gpg_import_func = self.getKeyForRepo
+         gpgca_import_func = self.getCAKeyForRepo
+@@ -1233,14 +1554,12 @@ Transaction Summary
+             self.repos.gpgca_import_func = gpgca_import_func
+ 
+     def interrupt_callback(self, cbobj):
+-        '''Handle CTRL-C's during downloads
+-
+-        If a CTRL-C occurs a URLGrabError will be raised to push the download
+-        onto the next mirror.  
+-        
+-        If two CTRL-C's occur in quick succession then yum will exit.
++        '''Handle CTRL-C's during downloads.  If a CTRL-C occurs a
++        URLGrabError will be raised to push the download onto the next
++        mirror.  If two CTRL-C's occur in quick succession then yum
++        will exit.
+ 
+-        @param cbobj: urlgrabber callback obj
++        :param cbobj: :class:`urlgrabber.grabber.CallbackObject`
+         '''
+         delta_exit_chk = 2.0      # Delta between C-c's so we treat as exit
+         delta_exit_str = _("two") # Human readable version of above
+@@ -1269,6 +1588,14 @@ to exit.
+ 
+     def download_callback_total_cb(self, remote_pkgs, remote_size,
+                                    download_start_timestamp):
++        """Outputs summary information about the download process.
++
++        :param remote_pkgs: a list of package objects that were downloaded
++        :param remote_size: the total amount of information that was
++           downloaded, in bytes
++        :param download_start_timestamp: the time when the download
++           process started, in seconds since the epoch
++        """
+         if len(remote_pkgs) <= 1:
+             return
+         if not hasattr(urlgrabber.progress, 'TerminalLine'):
+@@ -1434,8 +1761,17 @@ to exit.
+         return tids, printall
+ 
+     def historyListCmd(self, extcmds):
+-        """ Shows the user a list of data about the history. """
++        """Output a list of information about the history of yum
++        transactions.
++
++        :param extcmds: list of extra command line arguments
++        :return: (exit_code, [errors])
+ 
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++        """
+         tids, printall = self._history_list_transactions(extcmds)
+         if tids is None:
+             return 1, ['Failed history list']
+@@ -1564,6 +1900,16 @@ to exit.
+         return old[0]
+ 
+     def historyInfoCmd(self, extcmds):
++        """Output information about a transaction in history
++
++        :param extcmds: list of extra command line arguments
++        :return: (exit_code, [errors])
++
++        exit_code is::
++
++            0 = we're done, exit
++            1 = we've errored, exit with error string
++        """
+         def str2int(x):
+             try:
+                 return int(x)
+@@ -1833,6 +2179,13 @@ to exit.
+                               'Updated'      : _('Updated'),
+                               }
+     def historyInfoCmdPkgsAltered(self, old, pats=[]):
++        """Print information about how packages are altered in a transaction.
++
++        :param old: the :class:`history.YumHistoryTransaction` to
++           print information about
++        :param pats: a list of patterns.  Packages that match a patten
++           in *pats* will be highlighted in the output
++        """
+         last = None
+         #  Note that these don't use _simple_pkg() because we are showing what
+         # happened to them in the transaction ... not the difference between the
+@@ -1886,6 +2239,10 @@ to exit.
+                                         self._hpkg2from_repo(hpkg))
+ 
+     def historySummaryCmd(self, extcmds):
++        """Print a summary of transactions in history.
++
++        :param extcmds: list of extra command line arguments
++        """
+         tids, printall = self._history_list_transactions(extcmds)
+         if tids is None:
+             return 1, ['Failed history info']
+@@ -1946,6 +2303,10 @@ to exit.
+                              utf8_width_fill(uiacts, 16, 16), count)
+ 
+     def historyAddonInfoCmd(self, extcmds):
++        """Print addon information about transaction in history.
++
++        :param extcmds: list of extra command line arguments
++        """
+         tid = None
+         if len(extcmds) > 1:
+             tid = extcmds[1]
+@@ -1991,8 +2352,11 @@ to exit.
+             print ''
+ 
+     def historyPackageListCmd(self, extcmds):
+-        """ Shows the user a list of data about the history, from the point
+-            of a package(s) instead of via. transactions. """
++        """Print a list of information about transactions from history
++        that involve the given package or packages.
++
++        :param extcmds: list of extra command line arguments
++        """
+         tids = self.history.search(extcmds)
+         limit = None
+         if extcmds and not tids:
+@@ -2080,7 +2444,7 @@ to exit.
+ 
+ 
+ class DepSolveProgressCallBack:
+-    """provides text output callback functions for Dependency Solver callback"""
++    """A class to provide text output callback functions for Dependency Solver callback."""
+     
+     def __init__(self, ayum=None):
+         """requires yum-cli log and errorlog functions as arguments"""
+@@ -2089,6 +2453,25 @@ class DepSolveProgressCallBack:
+         self.ayum = ayum
+ 
+     def pkgAdded(self, pkgtup, mode):
++        """Print information about a package being added to the
++        transaction set.
++
++        :param pkgtup: tuple containing the package name, arch,
++           version, and repository
++        :param mode: a short string indicating why the package is
++           being added to the transaction set.
++
++        Valid current values for *mode* are::
++        
++           i = the package will be installed
++           u = the package will be an update
++           e = the package will be erased
++           r = the package will be reinstalled
++           d = the package will be a downgrade
++           o = the package will be obsoleting another package
++           ud = the package will be updated
++           od = the package will be obsoleted
++        """
+         modedict = { 'i': _('installed'),
+                      'u': _('an update'),
+                      'e': _('erased'),
+@@ -2104,43 +2487,85 @@ class DepSolveProgressCallBack:
+             modeterm)
+         
+     def start(self):
++        """Perform setup at the beginning of the dependency solving
++        process.
++        """
+         self.loops += 1
+         
+     def tscheck(self):
++        """Output a message stating that a transaction check is beginning."""
+         self.verbose_logger.log(logginglevels.INFO_2, _('--> Running transaction check'))
+         
+     def restartLoop(self):
++        """Output a message stating that dependency resolution is restarting."""
+         self.loops += 1
+         self.verbose_logger.log(logginglevels.INFO_2,
+             _('--> Restarting Dependency Resolution with new changes.'))
+         self.verbose_logger.debug('---> Loop Number: %d', self.loops)
+     
+     def end(self):
++        """Output a message stating that dependency resolution has finished."""
+         self.verbose_logger.log(logginglevels.INFO_2,
+             _('--> Finished Dependency Resolution'))
+ 
+     
+     def procReq(self, name, formatted_req):
++        """Output a message stating that the package *formatted_req*
++        is being processed as a dependency for the package *name*.
++
++        :param name: the name of the package that *formatted_req* is a
++           dependency of
++        :param formatted_req: a string representing the package that
++           is being processed as a dependency of *name*
++        """
+         self.verbose_logger.log(logginglevels.INFO_2,
+             _('--> Processing Dependency: %s for package: %s'), formatted_req,
+             name)
+ 
+     def procReqPo(self, po, formatted_req):
++        """Output a message stating that the package *formatted_req*
++        is being processed as a dependency for the package *po*.
++
++        :param po: the package object that *formatted_req* is a
++           dependency of
++        :param formatted_req: a string representing the package that
++           is being processed as a dependency of *po*
++        """
+         self.verbose_logger.log(logginglevels.INFO_2,
+             _('--> Processing Dependency: %s for package: %s'), formatted_req,
+             po)
+     
+     def groupRemoveReq(self, po, hits):
++        """Output a message stating that the given package will not be
++        removed. This method is used during leaf-only group remove
++        commands to indicate that the package will be kept.
++
++        :param po: the :class:`yum.packages.PackageObject` that will
++           not be removed
++        :param hits: unused
++        """
+         self.verbose_logger.log(logginglevels.INFO_2,
+             _('---> Keeping package: %s'), po)
+ 
+     def unresolved(self, msg):
++        """Output a message stating that there is an unresolved
++        dependency.
++
++        :param msg: string giving information about the unresolved
++        dependency
++        """
+         self.verbose_logger.log(logginglevels.INFO_2, _('--> Unresolved Dependency: %s'),
+             msg)
+ 
+     def format_missing_requires(self, reqPo, reqTup):
+-        """ Create a message for errorlist, non-cli users could also store this
+-            data somewhere and not print errorlist. """
++        """Return an error message stating that a package required to
++        fulfill a dependency is missing.
++
++        :param reqPo: the package object that has a dependency that
++           cannot be fulfilled
++        :param reqTup: the name, flags, and version of the package
++           needed to fulfil the dependency
++        """
+         needname, needflags, needversion = reqTup
+ 
+         yb = self.ayum
+@@ -2225,45 +2650,89 @@ class DepSolveProgressCallBack:
+         return msg
+     
+     def procConflict(self, name, confname):
++        """Print a message stating that two packages in the
++        transaction conflict.
++
++        :param name: the name of the first package involved in the
++           conflict 
++        :param confname: the name of the second package involved in
++           the conflict
++        """
+         self.verbose_logger.log(logginglevels.INFO_2,
+             _('--> Processing Conflict: %s conflicts %s'),
+                                 name, confname)
+ 
+     def procConflictPo(self, po, confname):
++        """Print a message stating that two packages in the
++        transaction conflict.
++
++        :param name: the first package object involved in the
++           conflict 
++        :param confname: the second package object involved in
++           the conflict
++        """
+         self.verbose_logger.log(logginglevels.INFO_2,
+             _('--> Processing Conflict: %s conflicts %s'),
+                                 po, confname)
+ 
+     def transactionPopulation(self):
++        """Output a message stating that the transaction set is being populated."""
++
+         self.verbose_logger.log(logginglevels.INFO_2, _('--> Populating transaction set '
+             'with selected packages. Please wait.'))
+     
+     def downloadHeader(self, name):
++        """Output a message stating that the header for the given
++        package is being downloaded.
++
++        :param name: the name of the package
++        """
+         self.verbose_logger.log(logginglevels.INFO_2, _('---> Downloading header for %s '
+             'to pack into transaction set.'), name)
+        
+ 
+ class CacheProgressCallback:
++    """A class to handle text output callbacks during metadata cache updates."""
+ 
+-    '''
+-    The class handles text output callbacks during metadata cache updates.
+-    '''
+-    
+     def __init__(self):
+         self.logger = logging.getLogger("yum.cli")
+         self.verbose_logger = logging.getLogger("yum.verbose.cli")
+         self.file_logger = logging.getLogger("yum.filelogging.cli")
+ 
+     def log(self, level, message):
++        """Output a log message.
++
++        :param level: the logging level for the message
++        :param message: the message
++        """
+         self.verbose_logger.log(level, message)
+ 
+     def errorlog(self, level, message):
++        """Output an errorlog message.
++
++        :param level: the logging level for the message
++        :param message: the message
++        """
+         self.logger.log(level, message)
+ 
+     def filelog(self, level, message):
++        """Output a file log message.
++
++        :param level: the logging level for the message
++        :param message: the message
++        """
+         self.file_logger.log(level, message)
+ 
+     def progressbar(self, current, total, name=None):
++        """Output the current status to the terminal using a progress
++        status bar.
++
++        :param current: a number representing the amount of work
++           already done
++        :param total: a number representing the total amount of work
++           to be done
++        :param name: a name to label the progress bar with
++        """
+         progressbar(current, total, name)
+ 
+ def _pkgname_ui(ayum, pkgname, ts_states=None):
+@@ -2316,10 +2785,7 @@ def _pkgname_ui(ayum, pkgname, ts_states=None):
+     return pkgname
+ 
+ class YumCliRPMCallBack(RPMBaseCallback):
+-
+-    """
+-    Yum specific callback class for RPM operations.
+-    """
++    """A Yum specific callback class for RPM operations."""
+ 
+     width = property(lambda x: _term_width())
+ 
+@@ -2337,11 +2803,31 @@ class YumCliRPMCallBack(RPMBaseCallback):
+     #  Installing things have pkg objects passed to the events, so only need to
+     # lookup for erased/obsoleted.
+     def pkgname_ui(self, pkgname, ts_states=('e', 'od', 'ud', None)):
+-        """ Get more information on a simple pkgname, if we can. """
++        """Return more information on a simple pkgname, if possible.
++
++        :param pkgname: the name of the package to find information about
++        :param ts_states: a tuple containing the states where the
++           package might be found
++        """
+         return _pkgname_ui(self.ayum, pkgname, ts_states)
+ 
+     def event(self, package, action, te_current, te_total, ts_current, ts_total):
+-        # this is where a progress bar would be called
++        """Output information about an rpm operation.  This may
++        include a text progress bar.
++
++        :param package: the package involved in the event
++        :param action: the type of action that is taking place.  Valid
++           values are given by
++           :func:`rpmtrans.RPMBaseCallback.action.keys()`
++        :param te_current: a number representing the amount of work
++           already done in the current transaction
++        :param te_total: a number representing the total amount of work
++           to be done in the current transaction
++        :param ts_current: the number of the current transaction in
++           transaction set
++        :param ts_total: the total number of transactions in the
++           transaction set
++        """
+         process = self.action[action]
+ 
+         if not hasattr(self, '_max_action_wid'):
+@@ -2366,6 +2852,7 @@ class YumCliRPMCallBack(RPMBaseCallback):
+         
+         if self.output and (sys.stdout.isatty() or te_current == te_total):
+             (fmt, wid1, wid2) = self._makefmt(percent, ts_current, ts_total,
++                                              progress=sys.stdout.isatty(),
+                                               pkgname=pkgname, wid1=wid1)
+             msg = fmt % (utf8_width_fill(process, wid1, wid1),
+                          utf8_width_fill(pkgname, wid2, wid2))
+@@ -2377,6 +2864,11 @@ class YumCliRPMCallBack(RPMBaseCallback):
+                 print " "
+ 
+     def scriptout(self, package, msgs):
++        """Print messages originating from a package script.
++
++        :param package: unused
++        :param msgs: the messages coming from the script
++        """
+         if msgs:
+             sys.stdout.write(to_unicode(msgs))
+             sys.stdout.flush()
+@@ -2431,6 +2923,15 @@ class YumCliRPMCallBack(RPMBaseCallback):
+ 
+ 
+ def progressbar(current, total, name=None):
++    """Output the current status to the terminal using a simple
++    text progress bar consisting of 50 # marks.
++
++    :param current: a number representing the amount of work
++       already done
++    :param total: a number representing the total amount of work
++       to be done
++    :param name: a name to label the progress bar with
++    """
+     """simple progress bar 50 # marks"""
+     
+     mark = '#'
 diff --git a/rpmUtils/arch.py b/rpmUtils/arch.py
 index 6082005..ad7bbb1 100644
 --- a/rpmUtils/arch.py
@@ -38,6 +2053,419 @@ index 6082005..ad7bbb1 100644
          return "ppc"
      elif myarch.startswith("arm"):
          return "arm"
+diff --git a/shell.py b/shell.py
+index 999bffc..636f12c 100644
+--- a/shell.py
++++ b/shell.py
+@@ -29,10 +29,7 @@ import yum.logginglevels as logginglevels
+ 
+ 
+ class YumShell(cmd.Cmd):
+-
+-    """
+-    Interactive yum shell.
+-    """
++    """A class to implement an interactive yum shell."""
+ 
+     def __init__(self, base):
+         cmd.Cmd.__init__(self)
+@@ -77,6 +74,11 @@ class YumShell(cmd.Cmd):
+         return inputs
+         
+     def script(self):
++        """Execute a script file in the yum shell.  The location of
++        the script file is supplied by the :class:`cli.YumBaseCli`
++        object that is passed as a parameter to the :class:`YumShell`
++        object when it is created.
++        """
+         try:
+             fd = open(self.file, 'r')
+         except IOError:
+@@ -90,6 +92,13 @@ class YumShell(cmd.Cmd):
+         return True
+             
+     def default(self, line):
++        """Handle the next line of input if there is not a dedicated
++        method of :class:`YumShell` to handle it.  This method will
++        handle yum commands that are not unique to the shell, such as
++        install, erase, etc.
++
++        :param line: the next line of input
++        """
+         if len(line) > 0 and line.strip()[0] == '#':
+             pass
+         else:
+@@ -117,9 +126,15 @@ class YumShell(cmd.Cmd):
+                 self.base.doCommands()
+     
+     def emptyline(self):
++        """Do nothing on an empty line of input."""
+         pass
+ 
+     def completenames(self, text, line, begidx, endidx):
++        """Return a list of possible completions of a command.
++
++        :param text: the command to be completed
++        :return: a list of possible completions of the command
++        """
+         ret = cmd.Cmd.completenames(self, text, line, begidx, endidx)
+         for command in self.base.yum_cli_commands:
+             if command.startswith(text) and command != "shell":
+@@ -127,6 +142,11 @@ class YumShell(cmd.Cmd):
+         return ret
+ 
+     def do_help(self, arg):
++        """Output help information.
++
++        :param arg: the command to ouput help information about. If
++           *arg* is an empty string, general help will be output.
++        """
+         msg = """
+     Shell specific arguments:
+       config - set config options
+@@ -166,21 +186,47 @@ class YumShell(cmd.Cmd):
+         self.verbose_logger.info(msg)
+         
+     def do_EOF(self, line):
++        """Exit the shell when EOF is reached.
++
++        :param line: unused
++        """
+         self.resultmsgs = ['Leaving Shell']
+         return True
+     
+     def do_quit(self, line):
++        """Exit the shell.
++
++        :param line: unused
++        """
+         self.resultmsgs = ['Leaving Shell']
+         return True
+     
+     def do_exit(self, line):
++        """Exit the shell.
++
++        :param line: unused
++        """
+         self.resultmsgs = ['Leaving Shell']
+         return True
+     
+     def do_ts(self, line):
++        """Handle the ts alias of the :func:`do_transaction` method.
++
++        :param line: the remainder of the line, containing the name of
++           a subcommand.  If no subcommand is given, run the list subcommand.
++        """
+         self.do_transaction(line)
+ 
+     def do_transaction(self, line):
++        """Execute the given transaction subcommand.  The list
++        subcommand outputs the contents of the transaction, the reset
++        subcommand clears the transaction, the solve subcommand solves
++        dependencies for the transaction, and the run subcommand
++        executes the transaction.
++
++        :param line: the remainder of the line, containing the name of
++           a subcommand.  If no subcommand is given, run the list subcommand.
++        """
+         (cmd, args, line) = self.parseline(line)
+         if cmd in ['list', None]:
+             self.verbose_logger.log(logginglevels.INFO_2,
+@@ -210,6 +256,15 @@ class YumShell(cmd.Cmd):
+             self.do_help('transaction')
+     
+     def do_config(self, line):
++        """Configure yum shell options.
++        
++        :param line: the remainder of the line, containing an option,
++           and then optionally a value in the form [option] [value].
++           Valid options are one of the following: debuglevel,
++           errorlevel, obsoletes, gpgcheck, assumeyes, exclude.  If no
++           value is given, print the current value.  If a value is
++           supplied, set the option to the given value.
++        """
+         (cmd, args, line) = self.parseline(line)
+         # logs
+         if cmd in ['debuglevel', 'errorlevel']:
+@@ -264,9 +319,23 @@ class YumShell(cmd.Cmd):
+             self.do_help('config')
+ 
+     def do_repository(self, line):
++        """Handle the repository alias of the :func:`do_repo` method.
++
++        :param line: the remainder of the line, containing the name of
++           a subcommand.
++        """
+         self.do_repo(line)
+         
+     def do_repo(self, line):
++        """Execute the given repo subcommand.  The list subcommand
++        lists repositories and their statuses, the enable subcommand
++        enables the given repository, and the disable subcommand
++        disables the given repository.
++
++        :param line: the remainder of the line, containing the name of
++           a subcommand and other parameters if required.  If no
++           subcommand is given, run the list subcommand.
++        """
+         (cmd, args, line) = self.parseline(line)
+         if cmd in ['list', None]:
+             # Munge things to run the repolist command
+@@ -338,6 +407,10 @@ class YumShell(cmd.Cmd):
+         print line
+         
+     def do_run(self, line):
++        """Run the transaction.
++
++        :param line: unused
++        """
+         if len(self.base.tsInfo) > 0:
+             try:
+                 (code, msgs) = self.base.buildTransaction()
+diff --git a/utils.py b/utils.py
+old mode 100644
+new mode 100755
+index ced6ba0..90b6fd4
+--- a/utils.py
++++ b/utils.py
+@@ -13,6 +13,8 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ 
++"""Various utility functions, and a utility class."""
++
+ import sys
+ import time
+ import exceptions
+@@ -29,6 +31,9 @@ import yum.plugins as plugins
+ from urlgrabber.progress import format_number
+ 
+ def suppress_keyboard_interrupt_message():
++    """Change settings so that nothing will be printed to the
++    terminal after an uncaught :class:`exceptions.KeyboardInterrupt`.
++    """
+     old_excepthook = sys.excepthook
+ 
+     def new_hook(type, value, traceback):
+@@ -40,10 +45,23 @@ def suppress_keyboard_interrupt_message():
+     sys.excepthook = new_hook
+ 
+ def jiffies_to_seconds(jiffies):
++    """Convert a number of jiffies to seconds, using the convention
++    that 100 jiffies = 1 second.
++
++    :param jiffies: a number of jiffies
++    :return: the equivalent number of seconds
++    """
+     Hertz = 100 # FIXME: Hack, need to get this, AT_CLKTCK elf note *sigh*
+     return int(jiffies) / Hertz
+ 
+ def seconds_to_ui_time(seconds):
++    """Return a human-readable string representation of the length of
++    a time interval given in seconds.
++
++    :param seconds: the length of the time interval in seconds
++    :return: a human-readable string representation of the length of
++    the time interval
++    """
+     if seconds >= 60 * 60 * 24:
+         return "%d day(s) %d:%02d:%02d" % (seconds / (60 * 60 * 24),
+                                            (seconds / (60 * 60)) % 24,
+@@ -55,6 +73,12 @@ def seconds_to_ui_time(seconds):
+     return "%02d:%02d" % ((seconds / 60), seconds % 60)
+ 
+ def get_process_info(pid):
++    """Return information about a process taken from
++    /proc/*pid*/status, /proc/stat/, and /proc/*pid*/stat.
++
++    :param pid: the process id number
++    :return: a dictionary containing information about the process
++    """
+     if not pid:
+         return
+ 
+@@ -106,6 +130,16 @@ def get_process_info(pid):
+     return ps
+ 
+ def show_lock_owner(pid, logger):
++    """Output information about another process that is holding the
++    yum lock.
++
++    :param pid: the process id number of the process holding the yum
++       lock
++    :param logger: the logger to output the information to
++    :return: a dictionary containing information about the process.
++       This is the same as the dictionary returned by
++       :func:`get_process_info`.
++    """
+     ps = get_process_info(pid)
+     if not ps:
+         return None
+@@ -130,9 +164,16 @@ def show_lock_owner(pid, logger):
+ 
+ 
+ def exception2msg(e):
+-    """ DIE python DIE! Which one works:
+-        to_unicode(e.value); unicode(e); str(e); 
+-        Call this so you don't have to care. """
++    """Convert an exception to a message.  This function will convert
++    the exception using to_unicode, unicode, or str, whichever works correctly.
++
++    :param e: an exception
++    :return: a string representation of the exception
++    """
++
++    # DIE python DIE! Which one works:
++    # to_unicode(e.value); unicode(e); str(e); 
++    # Call this so you don't have to care.
+     try:
+         return to_unicode(e.value)
+     except:
+@@ -151,6 +192,8 @@ def exception2msg(e):
+ 
+ 
+ class YumUtilBase(YumBaseCli):
++    """A class to extend the yum cli for utilities."""
++    
+     def __init__(self,name,ver,usage):
+         YumBaseCli.__init__(self)
+         self._parser = YumOptionParser(base=self,utils=True,usage=usage)
+@@ -167,11 +210,22 @@ class YumUtilBase(YumBaseCli):
+             self.run_with_package_names.add("yum-utils")
+ 
+     def exUserCancel(self):
++        """Output a message stating that the operation was cancelled
++        by the user.
++
++        :return: the exit code
++        """
+         self.logger.critical(_('\n\nExiting on user cancel'))
+         if self.unlock(): return 200
+         return 1
+ 
+     def exIOError(self, e):
++        """Output a message stating that the program is exiting due to
++        an IO exception.
++
++        :param e: the IO exception
++        :return: the exit code
++        """
+         if e.errno == 32:
+             self.logger.critical(_('\n\nExiting on Broken Pipe'))
+         else:
+@@ -180,10 +234,13 @@ class YumUtilBase(YumBaseCli):
+         return 1
+ 
+     def exPluginExit(self, e):
+-        '''Called when a plugin raises PluginYumExit.
++        """Called when a plugin raises
++           :class:`yum.plugins.PluginYumExit`.  Log the plugin's exit
++           message if one was supplied.
+ 
+-        Log the plugin's exit message if one was supplied.
+-        ''' # ' xemacs hack
++        :param e: the exception
++        :return: the exit code
++        """ # ' xemacs hack
+         exitmsg = exception2msg(e)
+         if exitmsg:
+             self.logger.warn('\n\n%s', exitmsg)
+@@ -191,11 +248,20 @@ class YumUtilBase(YumBaseCli):
+         return 1
+ 
+     def exFatal(self, e):
++        """Output a message stating that a fatal error has occurred.
++
++        :param e: the exception
++        :return: the exit code
++        """
+         self.logger.critical('\n\n%s', exception2msg(e))
+         if self.unlock(): return 200
+         return 1
+         
+     def unlock(self):
++        """Release the yum lock.
++
++        :return: the exit code
++        """
+         try:
+             self.closeRpmDB()
+             self.doUnlock()
+@@ -205,13 +271,27 @@ class YumUtilBase(YumBaseCli):
+         
+         
+     def getOptionParser(self):
++        """Return the :class:`cli.YumOptionParser` for this object.
++
++        :return: the :class:`cli.YumOptionParser` for this object
++        """
+         return self._parser        
+ 
+     def getOptionGroup(self):
+-        """ Get an option group to add non inherited options"""
++        """Return an option group to add non inherited options.
++
++        :return: a :class:`optparse.OptionGroup` for adding options
++           that are not inherited from :class:`YumBaseCli`.
++        """
+         return self._option_group    
+     
+     def waitForLock(self):
++        """Establish the yum lock.  If another process is already
++        holding the yum lock, by default this method will keep trying
++        to establish the lock until it is successful.  However, if
++        :attr:`self.conf.exit_on_lock` is set to True, it will
++        raise a :class:`Errors.YumBaseError`.
++        """
+         lockerr = ""
+         while True:
+             try:
+@@ -233,6 +313,13 @@ class YumUtilBase(YumBaseCli):
+         print "%s - %s (yum - %s)" % (self._utilName,self._utilVer,yum.__version__)
+         
+     def doUtilConfigSetup(self,args = sys.argv[1:],pluginsTypes=(plugins.TYPE_CORE,)):
++        """Parse command line options, and perform configuration.
++
++        :param args: list of arguments to use for configuration
++        :param pluginsTypes: a sequence specifying the types of
++           plugins to load
++        :return: a dictionary containing the values of command line options
++        """
+         # Parse only command line options that affect basic yum setup
+         opts = self._parser.firstParse(args)
+ 
+@@ -305,8 +392,9 @@ class YumUtilBase(YumBaseCli):
+         return opts
+ 
+     def doUtilYumSetup(self):
+-        """do a default setup for all the normal/necessary yum components,
+-           really just a shorthand for testing"""
++        """Do a default setup for all the normal or necessary yum components;
++           this method is mostly just a used for testing.
++        """
+         # FIXME - we need another way to do this, I think.
+         try:
+             self.waitForLock()
+@@ -319,6 +407,11 @@ class YumUtilBase(YumBaseCli):
+             sys.exit(1)
+ 
+     def doUtilBuildTransaction(self, unfinished_transactions_check=True):
++        """Build the transaction.
++
++        :param unfinished_transactions_check: whether to check if an
++           unfinished transaction has been saved
++        """
+         try:
+             (result, resultmsgs) = self.buildTransaction(unfinished_transactions_check = unfinished_transactions_check)
+         except plugins.PluginYumExit, e:
+@@ -361,6 +454,7 @@ class YumUtilBase(YumBaseCli):
+         self.verbose_logger.log(logginglevels.INFO_2, _('\nDependencies Resolved'))
+         
+     def doUtilTransaction(self):
++        """Perform the transaction."""
+ 
+         try:
+             return_code = self.doTransaction()
 diff --git a/yum.spec b/yum.spec
 index abd203f..9e7ed43 100644
 --- a/yum.spec
@@ -51,7 +2479,7 @@ index abd203f..9e7ed43 100644
  License: GPLv2+
  Group: System Environment/Base
 diff --git a/yum/__init__.py b/yum/__init__.py
-index 99039e0..e9bc1f9 100644
+index 99039e0..12c2bdd 100644
 --- a/yum/__init__.py
 +++ b/yum/__init__.py
 @@ -1242,13 +1242,15 @@ class YumBase(depsolve.Depsolve):
@@ -92,6 +2520,192 @@ index 99039e0..e9bc1f9 100644
              raise Errors.RpmDBError, _('Package tuple %s could not be found in rpmdb') % str(pkgtup)
  
          # Dito. FIXME from getPackageObject() for len() > 1 ... :)
+@@ -4725,7 +4727,9 @@ class YumBase(depsolve.Depsolve):
+                     # Try installing/updating GPG key
+                     self._getKeyImportMessage(info, keyurl)
+                     rc = False
+-                    if self.conf.assumeyes:
++                    if self.conf.assumeno:
++                        rc = False
++                    elif self.conf.assumeyes:
+                         rc = True
+                         
+                     # grab the .sig/.asc for the keyurl, if it exists
+@@ -4819,8 +4823,11 @@ class YumBase(depsolve.Depsolve):
+                 if not key_installed:
+                     self._getKeyImportMessage(info, keyurl, keytype)
+                     rc = False
+-                    if self.conf.assumeyes:
++                    if self.conf.assumeno:
++                        rc = False
++                    elif self.conf.assumeyes:
+                         rc = True
++
+                     elif callback:
+                         rc = callback({"repo": repo, "userid": info['userid'],
+                                         "hexkeyid": info['hexkeyid'], "keyurl": keyurl,
+diff --git a/yum/config.py b/yum/config.py
+index d09511f..dbf1784 100644
+--- a/yum/config.py
++++ b/yum/config.py
+@@ -664,6 +664,7 @@ class YumConf(StartupConf):
+     tsflags = ListOption()
+ 
+     assumeyes = BoolOption(False)
++    assumeno  = BoolOption(False)
+     alwaysprompt = BoolOption(True)
+     exactarch = BoolOption(True)
+     tolerant = BoolOption(True)
+@@ -1028,7 +1029,10 @@ def _getsysver(installroot, distroverpkg):
+     if idx.count() == 0:
+         releasever = '$releasever'
+     else:
+-        hdr = idx.next()
++        try:
++            hdr = idx.next()
++        except StopIteration:
++            raise Errors.YumBaseError("Error: rpmdb failed release provides. Try: rpm --rebuilddb")
+         releasever = hdr['version']
+         del hdr
+     del idx
+@@ -1069,7 +1073,7 @@ def writeRawRepoFile(repo,only=None):
+         #  If the value is the same, but just interpreted ... when we don't want
+         # to keep the interpreted values.
+         if (name in ini[section_id] and
+-            ovalue == varReplace(ini[section_id][name], yumvar)):
++            ovalue == varReplace(ini[section_id][name], repo.yumvar)):
+             ovalue = ini[section_id][name]
+ 
+         if name not in cfgOptions and option.default == value:
+diff --git a/yum/misc.py b/yum/misc.py
+index 2f6ddfe..37c572b 100644
+--- a/yum/misc.py
++++ b/yum/misc.py
+@@ -940,14 +940,16 @@ def unlink_f(filename):
+         if e.errno != errno.ENOENT:
+             raise
+ 
+-def stat_f(filename):
++def stat_f(filename, ignore_EACCES=False):
+     """ Call os.stat(), but don't die if the file isn't there. Returns None. """
+     try:
+         return os.stat(filename)
+     except OSError, e:
+-        if e.errno not in (errno.ENOENT, errno.ENOTDIR):
+-            raise
+-        return None
++        if e.errno in (errno.ENOENT, errno.ENOTDIR):
++            return None
++        if ignore_EACCES and e.errno == errno.EACCES:
++            return None
++        raise
+ 
+ def _getloginuid():
+     """ Get the audit-uid/login-uid, if available. None is returned if there
+diff --git a/yum/packages.py b/yum/packages.py
+index 5ef9951..e055edf 100644
+--- a/yum/packages.py
++++ b/yum/packages.py
+@@ -1217,7 +1217,7 @@ class YumAvailablePackage(PackageObject, RpmBase):
+                     prcostring += ''' ver="%s"''' % misc.to_xml(v, attrib=True)
+                 if r:
+                     prcostring += ''' rel="%s"''' % misc.to_xml(r, attrib=True)
+-            if pre:
++            if pre != "0":
+                 prcostring += ''' pre="%s"''' % pre
+                     
+             prcostring += "/>\n"
+diff --git a/yum/rpmsack.py b/yum/rpmsack.py
+index e289a7a..ef6fbd5 100644
+--- a/yum/rpmsack.py
++++ b/yum/rpmsack.py
+@@ -48,6 +48,17 @@ def _open_no_umask(*args):
+ 
+     return ret
+ 
++def _makedirs_no_umask(*args):
++    """ Annoying people like to set umask's for root, which screws everything
++        up for user readable stuff. """
++    oumask = os.umask(022)
++    try:
++        ret = os.makedirs(*args)
++    finally:
++        os.umask(oumask)
++
++    return ret
++
+ def _iopen(*args):
+     """ IOError wrapper BS for open, stupid exceptions. """
+     try:
+@@ -364,7 +375,8 @@ class RPMDBPackageSack(PackageSackBase):
+             pkg = self.searchNevra(n, e, v, r, a)
+             if not pkg:
+                 # Wibble?
+-                self._deal_with_bad_rpmdbcache("dCDPT(pkg checksums)")
++                self._deal_with_bad_rpmdbcache("dCDPT(pkg checksums): %s" %
++                                               txmbr)
+                 continue
+ 
+             pkg = pkg[0]
+@@ -1002,7 +1014,8 @@ class RPMDBPackageSack(PackageSackBase):
+             (n, a, e, v, r) = pkgtup
+             pkg = self.searchNevra(n, e, v, r, a)
+             if not pkg:
+-                self._deal_with_bad_rpmdbcache("pkg checksums")
++                self._deal_with_bad_rpmdbcache("pkg checksums: %s-%s:%s-%s.%s" %
++                                               (n, e, v, r, a))
+                 continue
+             pkg = pkg[0]
+             (T, D) = checksum_data[pkgtup]
+@@ -1088,7 +1101,7 @@ class RPMDBPackageSack(PackageSackBase):
+                 return
+ 
+             try:
+-                os.makedirs(self._cachedir)
++                _makedirs_no_umask(self._cachedir)
+             except (IOError, OSError), e:
+                 return
+ 
+@@ -1562,7 +1575,7 @@ class RPMDBAdditionalData(object):
+         self._packages = {} # pkgid = dir
+         if not os.path.exists(self.conf.db_path):
+             try:
+-                os.makedirs(self.conf.db_path)
++                _makedirs_no_umask(self.conf.db_path)
+             except (IOError, OSError), e:
+                 # some sort of useful thing here? A warning?
+                 return
+@@ -1708,7 +1721,7 @@ class RPMDBAdditionalDataPackage(object):
+     def _write(self, attr, value):
+         # check for self._conf.writable before going on?
+         if not os.path.exists(self._mydir):
+-            os.makedirs(self._mydir)
++            _makedirs_no_umask(self._mydir)
+ 
+         attr = _sanitize(attr)
+         if attr in self._read_cached_data:
+@@ -1753,7 +1766,7 @@ class RPMDBAdditionalDataPackage(object):
+         if attr.endswith('.tmp'):
+             raise AttributeError, "%s has no attribute %s" % (self, attr)
+ 
+-        info = misc.stat_f(fn)
++        info = misc.stat_f(fn, ignore_EACCES=True)
+         if info is None:
+             raise AttributeError, "%s has no attribute %s" % (self, attr)
+ 
+diff --git a/yum/sqlitesack.py b/yum/sqlitesack.py
+index 8a6f6f3..19193ad 100644
+--- a/yum/sqlitesack.py
++++ b/yum/sqlitesack.py
+@@ -406,7 +406,7 @@ class YumAvailablePackageSqlite(YumAvailablePackage, PackageObject, RpmBase):
+         requires = []
+         for ob in cur:
+             pre = "0"
+-            if ob['pre'].lower() in ['TRUE', 1]:
++            if ob['pre'].lower() in ['true', 1]:
+                 pre = "1"
+             prco_set = (_share_data(ob['name']), _share_data(ob['flags']),
+                         (_share_data(ob['epoch']),
 diff --git a/yumcommands.py b/yumcommands.py
 index 4dcbea7..3a985c3 100644
 --- a/yumcommands.py
@@ -1926,3 +4540,67 @@ index 4dcbea7..3a985c3 100644
 +        """
          return True
  
+diff --git a/yummain.py b/yummain.py
+index 9f79f4f..e17f1e3 100755
+--- a/yummain.py
++++ b/yummain.py
+@@ -35,7 +35,7 @@ import cli
+ from utils import suppress_keyboard_interrupt_message, show_lock_owner, exception2msg
+ 
+ def main(args):
+-    """This does all the real work"""
++    """Run the yum program from a command line interface."""
+ 
+     yum.misc.setup_locale(override_time=True)
+ 
+@@ -248,6 +248,11 @@ def main(args):
+     return return_code
+ 
+ def hotshot(func, *args, **kwargs):
++    """Profile the given function using the hotshot profiler.
++
++    :param func: the function to profile
++    :return: the return code given by the hotshot profiler
++    """
+     import hotshot.stats
+     fn = os.path.expanduser("~/yum.prof")
+     prof = hotshot.Profile(fn)
+@@ -257,6 +262,11 @@ def hotshot(func, *args, **kwargs):
+     return rc
+ 
+ def cprof(func, *args, **kwargs):
++    """Profile the given function using the cprof profiler.
++
++    :param func: the function to profile
++    :return: the return code given by the cprof profiler
++    """
+     import cProfile, pstats
+     fn = os.path.expanduser("~/yum.prof")
+     prof = cProfile.Profile()
+@@ -266,6 +276,10 @@ def cprof(func, *args, **kwargs):
+     return rc
+ 
+ def print_stats(stats):
++    """Print out information from a :class:`Stats` object.
++
++    :param stats: the :class:`Stats` object to print information from
++    """
+     stats.strip_dirs()
+     stats.sort_stats('time', 'calls')
+     stats.print_stats(20)
+@@ -273,7 +287,14 @@ def print_stats(stats):
+     stats.print_stats(40)
+ 
+ def user_main(args, exit_code=False):
+-    """ This calls one of the multiple main() functions based on env. vars """
++    """Call one of the multiple main() functions based on environment variables.
++
++    :param args: command line arguments passed into yum
++    :param exit_code: if *exit_code* is True, this function will exit
++       python with its exit code when it has finished executing.
++       Otherwise, it will return its exit code.
++    :return: the exit code from yum execution
++    """
+     errcode = None
+     if 'YUM_PROF' in os.environ:
+         if os.environ['YUM_PROF'] == 'cprof':
diff --git a/yum.spec b/yum.spec
index c83aec4..b7a3302 100644
--- a/yum.spec
+++ b/yum.spec
@@ -7,7 +7,7 @@
 Summary: RPM package installer/updater/manager
 Name: yum
 Version: 3.4.3
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: GPLv2+
 Group: System Environment/Base
 Source0: http://yum.baseurl.org/download/3.4/%{name}-%{version}.tar.gz
@@ -248,6 +248,14 @@ exit 0
 %config(noreplace) %{_sysconfdir}/sysconfig/yum-cron
 
 %changelog
+* Fri Jul 15 2011 James Antill <james at fedoraproject.org> - 3.4.3-4
+- update to latest HEAD
+- Weird old bugs fixed for new createrepo code.
+- Add --assumeno and an easter egg! Also allow remove to use alwaysprompt.
+- Fix \r appearing on serial console etc. BZ 720088.
+- Fix umask on mkdir() as well as open. BZ 719467.
+- Fix traceback when enabling/disabling repos. in GUI.
+
 * Thu Jun 30 2011 James Antill <james at fedoraproject.org> - 3.4.3-3
 - Fix the skip broken tuples => dict. bug. BZ 717973.
 


More information about the scm-commits mailing list