diff --git a/yum/depsolve.py b/yum/depsolve.py index ad47a1d..1c65621 100644 --- a/yum/depsolve.py +++ b/yum/depsolve.py @@ -492,32 +492,14 @@ class Depsolve(object): thisarch = requiringPo.arch newest = provSack.returnNewestByNameArch() if len(newest) > 1: # there's no way this can be zero + best = newest[0] - for po in newest[1:]: - if thisarch != 'noarch': - best_dist = archDifference(thisarch, best.arch) - if isMultiLibArch(): # only go to the next one if we're multilib - i686 can satisfy i386 deps - if best_dist == 0: # can't really use best's arch anyway... - best = po # just try the next one - can't be much worse - continue + old_best = None + while best != old_best: + old_best = best + best = self._compare_providers(newest, best, thisarch) + - po_dist = archDifference(thisarch, po.arch) - if po_dist > 0 and best_dist > po_dist: - best = po - continue - - if best_dist == po_dist: - if len(po.name) < len(best.name): - best=po - continue - - elif len(po.name) < len(best.name): - best = po - elif len(po.name) == len(best.name): - # compare arch - arch = rpmUtils.arch.getBestArchFromList([po.arch, best.arch]) - if arch == po.arch: - best = po elif len(newest) == 1: best = newest[0] @@ -922,6 +904,48 @@ class Depsolve(object): return installed _isPackageInstalled = isPackageInstalled + def _compare_providers(self, pkgs, bestpkg, requiring_arch): + + for po in pkgs: + if po == bestpkg: # if we're comparing the same one, skip it + continue + + obsoleted = False + for obs in po.obsoletes: + if bestpkg.inPrcoRange('provides', obs): + return po + + # make sure the best doesn't obsolete this po - if it does we're done + # we do this b/c it is possible for two entries to oscillate in this + # test - obsolete should trump no matter what + # NOTE: mutually obsoleting providers is completely and utterly doom + for obs in bestpkg.obsoletes: + if po.inPrcoRange('provides', obs): + return bestpkg + + if requiring_arch != 'noarch': + best_dist = archDifference(requiring_arch, bestpkg.arch) + if isMultiLibArch(): # only go to the next one if we're multilib - i686 can satisfy i386 deps + if best_dist == 0: # can't really use best's arch anyway... + return po # just try the next one - can't be much worse + + + po_dist = archDifference(requiring_arch, po.arch) + if po_dist > 0 and best_dist > po_dist: + return po + + if best_dist == po_dist: + if len(po.name) < len(bestpkg.name): + return po + + elif len(po.name) < len(bestpkg.name): + return po + elif len(po.name) == len(bestpkg.name): + # compare arch + arch = rpmUtils.arch.getBestArchFromList([po.arch, bestpkg.arch]) + if arch == po.arch: + return po + class DepCheck(object): """object that YumDepsolver uses to see what things are needed to close diff --git a/yum/packages.py b/yum/packages.py index 2a650f0..48fd524 100644 --- a/yum/packages.py +++ b/yum/packages.py @@ -247,6 +247,8 @@ class RpmBase(object): return False def __ne__(self, other): + if not other: + return True if comparePoEVR(self, other) != 0 or self.arch != other.arch or self.name != other.name: return True return False