From 4486d0af6787b11a5ce4b9ed6410ce98ea096336 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Fri, 18 Dec 2009 08:30:03 +0000 Subject: [PATCH] Merged from trunk -r15053:15056 | 15054 | In movefile mtime preservation code, simply round down to | | zmedico | the nearest whole second since python's float cannot | | | preserve the st_mtim.tv_nsec field with complete precision. | | | Note that we have to use stat_obj[stat.ST_MTIME] here | | | because the float stat_obj.st_mtime rounds *up* sometimes. | | 15055 | Bug #296641 - Avoid UnicodeEncodeError with python2 in | | zmedico | eapi_is_supported() triggered by corrupt EAPI. | | 15056 | Inside depgraph._validate_blockers(), do not consider | | zmedico | blockers in DEPEND of installed packages, since DEPEND is | | | supposed to be irrelevant for packages after they are built. | svn path=/main/branches/prefix/; revision=15117 --- pym/_emerge/Blocker.py | 2 +- pym/_emerge/depgraph.py | 16 ++++++++++++--- pym/portage/__init__.py | 44 +++++++++++++---------------------------- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/pym/_emerge/Blocker.py b/pym/_emerge/Blocker.py index fcebb8b37..c9815d71a 100644 --- a/pym/_emerge/Blocker.py +++ b/pym/_emerge/Blocker.py @@ -14,7 +14,7 @@ import portage class Blocker(Task): __hash__ = Task.__hash__ - __slots__ = ("root", "atom", "cp", "eapi", "satisfied") + __slots__ = ("root", "atom", "cp", "eapi", "priority", "satisfied") def __init__(self, **kwargs): Task.__init__(self, **kwargs) diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 9b7274e00..766b188fd 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -743,7 +743,7 @@ class depgraph(object): # the parent is or will be installed. blocker = Blocker(atom=dep.atom, eapi=dep.parent.metadata["EAPI"], - root=dep.parent.root) + priority=dep.priority, root=dep.parent.root) self._dynamic_config._blocker_parents.add(blocker, dep.parent) return 1 @@ -2809,7 +2809,10 @@ class depgraph(object): # due to the performance penalty that is incurred by all the # additional dep_check calls that are required. - dep_keys = ["DEPEND","RDEPEND","PDEPEND"] + # For installed packages, always ignore blockers from DEPEND since + # only runtime dependencies should be relevant for packages that + # are already built. + dep_keys = ["RDEPEND", "PDEPEND"] for myroot in self._frozen_config.trees: vardb = self._frozen_config.trees[myroot]["vartree"].dbapi portdb = self._frozen_config.trees[myroot]["porttree"].dbapi @@ -2852,6 +2855,11 @@ class depgraph(object): self._dynamic_config._irrelevant_blockers.child_nodes(pkg)) except KeyError: pass + if blockers: + # Select just the runtime blockers. + blockers = [blocker for blocker in blockers \ + if blocker.priority.runtime or \ + blocker.priority.runtime_post] if blockers is not None: blockers = set(blocker.atom for blocker in blockers) @@ -2932,7 +2940,9 @@ class depgraph(object): try: for atom in blocker_atoms: blocker = Blocker(atom=atom, - eapi=pkg.metadata["EAPI"], root=myroot) + eapi=pkg.metadata["EAPI"], + priority=self._priority(runtime=True), + root=myroot) self._dynamic_config._blocker_parents.add(blocker, pkg) except portage.exception.InvalidAtom as e: depstr = " ".join(vardb.aux_get(pkg.cpv, dep_keys)) diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index cdbbc8e2c..074e16a31 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -6096,7 +6096,11 @@ def _eapi_is_deprecated(eapi): return eapi in _deprecated_eapis def eapi_is_supported(eapi): - eapi = str(eapi).strip() + if not isinstance(eapi, basestring): + # Only call str() when necessary since with python2 it + # can trigger UnicodeEncodeError if EAPI is corrupt. + eapi = str(eapi) + eapi = eapi.strip() if _eapi_is_deprecated(eapi): return True @@ -7671,37 +7675,17 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None, if newmtime is not None: os.utime(dest, (newmtime, newmtime)) else: + newmtime = sstat[stat.ST_MTIME] if renamefailed: - # If rename succeeded then this is not necessary, since - # rename automatically preserves timestamps with complete - # precision. - if sstat[stat.ST_MTIME] == long(sstat.st_mtime): - newmtime = sstat.st_mtime - else: - # Prevent mtime from rounding up to the next second. - # Generate nanosecond resolution (9 decimal places) in - # order to ensure that the floating point representation - # is the highest value possible without rounding up. - int_mtime = sstat[stat.ST_MTIME] - mtime_str = "%i." % int_mtime - nonzero_digits = 0 - decimal_places = 9 - for i in range(decimal_places): - for digit in range(9, -1, -1): - digit_str = str(digit) - if int_mtime == long(float(mtime_str + digit_str)): - break - if digit > 0: - nonzero_digits += 1 - mtime_str += digit_str - - if nonzero_digits > 0: - newmtime = float(mtime_str) - else: - newmtime = int_mtime - + # If rename succeeded then timestamps are automatically + # preserved with complete precision because the source + # and destination inode are the same. Otherwise, round + # down to the nearest whole second since python's float + # st_mtime cannot be used to preserve the st_mtim.tv_nsec + # field with complete precision. Note that we have to use + # stat_obj[stat.ST_MTIME] here because the float + # stat_obj.st_mtime rounds *up* sometimes. os.utime(dest, (newmtime, newmtime)) - newmtime = sstat[stat.ST_MTIME] except OSError: # The utime can fail here with EPERM even though the move succeeded. # Instead of failing, use stat to return the mtime if possible. -- 2.26.2