From a8bdcd1261ffff6531a2934de5e3e1f52e095172 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sun, 28 Jun 2009 13:10:08 +0000 Subject: [PATCH] Merged from trunk -r13690:13696 | 13691 | * Add a Package.invalid attribute to store messages about | | zmedico | invalid LICENSE, PROPERTIES, PROVIDE, and RESTRICT metadata. | | | Use it to mask invalid packages when necessary. * Evaluate | | | USE conditional values in Package.metadata when the are | | | accessed. | | 13692 | Add a Package.metadata.properties attribute containing a | | zmedico | list of enabled PROPERTIES values. | | 13693 | Add a Package.metadata.restrict attribute containing a list | | zmedico | of enabled RESTRICT values. | | 13694 | Make config.regenerate() detect api-level updates to | | zmedico | ACCEPT_LICENSE, for use in implementing the "free" filter | | | for the packagekit backend. | | 13695 | Make dbapi.cp_list() raise NotImplementedError. | | zmedico | | | 13696 | Use @property instead of __getattribute__ to implement lazy | | zmedico | Package.iuse.regex initialization. | svn path=/main/branches/prefix/; revision=13718 --- pym/_emerge/EbuildFetchonly.py | 3 +- pym/_emerge/Package.py | 71 ++++++++++++++++++++++++---------- pym/_emerge/Scheduler.py | 9 +---- pym/_emerge/depgraph.py | 31 ++++----------- pym/_emerge/visible.py | 2 + pym/portage/__init__.py | 23 ++++++----- pym/portage/dbapi/__init__.py | 2 +- 7 files changed, 76 insertions(+), 65 deletions(-) diff --git a/pym/_emerge/EbuildFetchonly.py b/pym/_emerge/EbuildFetchonly.py index e89d30fae..1b2f14345 100644 --- a/pym/_emerge/EbuildFetchonly.py +++ b/pym/_emerge/EbuildFetchonly.py @@ -24,9 +24,8 @@ class EbuildFetchonly(SlotObject): ebuild_path = portdb.findname(pkg.cpv) settings.setcpv(pkg) debug = settings.get("PORTAGE_DEBUG") == "1" - restrict_fetch = 'fetch' in settings['PORTAGE_RESTRICT'].split() - if restrict_fetch: + if 'fetch' in pkg.metadata.restrict: rval = self._execute_with_builddir() else: rval = portage.doebuild(ebuild_path, "fetch", diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py index c5dcd30e2..d7284ce3a 100644 --- a/pym/_emerge/Package.py +++ b/pym/_emerge/Package.py @@ -26,7 +26,7 @@ class Package(Task): "installed", "metadata", "onlydeps", "operation", "root_config", "type_name", "category", "counter", "cp", "cpv_split", - "inherited", "iuse", "mtime", + "inherited", "invalid", "iuse", "mtime", "pf", "pv_split", "root", "slot", "slot_atom",) + \ ("_use",) @@ -54,6 +54,11 @@ class Package(Task): self.cpv_split = portage.catpkgsplit(self.cpv) self.pv_split = self.cpv_split[1:] + def _invalid_metadata(self, msg): + if self.invalid is None: + self.invalid = [] + self.invalid.append(msg) + class _use_class(object): __slots__ = ("__weakref__", "enabled") @@ -69,7 +74,9 @@ class Package(Task): class _iuse(object): - __slots__ = ("__weakref__", "all", "enabled", "disabled", "iuse_implicit", "regex", "tokens") + __slots__ = ("__weakref__", "all", "enabled", "disabled", + "iuse_implicit", "tokens") + \ + ('_regex',) def __init__(self, tokens, iuse_implicit): self.tokens = tuple(tokens) @@ -89,20 +96,23 @@ class Package(Task): self.disabled = frozenset(disabled) self.all = frozenset(chain(enabled, disabled, other)) - def __getattribute__(self, name): - if name == "regex": - try: - return object.__getattribute__(self, "regex") - except AttributeError: - all = object.__getattribute__(self, "all") - iuse_implicit = object.__getattribute__(self, "iuse_implicit") - # Escape anything except ".*" which is supposed - # to pass through from _get_implicit_iuse() - regex = (re.escape(x) for x in chain(all, iuse_implicit)) - regex = "^(%s)$" % "|".join(regex) - regex = regex.replace("\\.\\*", ".*") - self.regex = re.compile(regex) - return object.__getattribute__(self, name) + @property + def regex(self): + """ + @returns: A regular expression that matches valid USE values which + may be specified in USE dependencies. + """ + try: + return self._regex + except AttributeError: + # Escape anything except ".*" which is supposed + # to pass through from _get_implicit_iuse() + regex = (re.escape(x) for x in \ + chain(self.all, self.iuse_implicit)) + regex = "^(%s)$" % "|".join(regex) + regex = re.compile(regex.replace("\\.\\*", ".*")) + self._regex = regex + return regex def _get_hash_key(self): hash_key = getattr(self, "_hash_key", None) @@ -158,6 +168,8 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): __slots__ = ("_pkg",) _wrapped_keys = frozenset( ["COUNTER", "INHERITED", "IUSE", "SLOT", "_mtime_"]) + _use_conditional_keys = frozenset( + ['LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',]) def __init__(self, pkg, metadata): _PackageMetadataWrapperBase.__init__(self) @@ -172,11 +184,17 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): def __getitem__(self, k): v = _PackageMetadataWrapperBase.__getitem__(self, k) - if k in ('PROVIDE', 'LICENSE',): + if k in self._use_conditional_keys: if '?' in v: - v = paren_enclose(paren_normalize(use_reduce( - paren_reduce(v), uselist=self._pkg.use.enabled))) - self[k] = v + try: + v = paren_enclose(paren_normalize(use_reduce( + paren_reduce(v), uselist=self._pkg.use.enabled))) + except portage.exception.InvalidDependString: + # This error should already have been registered via + # self._pkg._invalid_metadata(). + pass + else: + self[k] = v elif k == 'USE' and not self._pkg.built: if not v: @@ -193,6 +211,11 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): _PackageMetadataWrapperBase.__setitem__(self, k, v) if k in self._wrapped_keys: getattr(self, "_set_" + k.lower())(k, v) + elif k in self._use_conditional_keys: + try: + use_reduce(paren_reduce(v), matchall=1) + except portage.exception.InvalidDependString, e: + self._pkg._invalid_metadata("%s: %s" % (k, e)) def _set_inherited(self, k, v): if isinstance(v, basestring): @@ -221,3 +244,11 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): except ValueError: v = 0 self._pkg.mtime = v + + @property + def properties(self): + return self['PROPERTIES'].split() + + @property + def restrict(self): + return self['RESTRICT'].split() diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py index 2279ab26c..fa20b8019 100644 --- a/pym/_emerge/Scheduler.py +++ b/pym/_emerge/Scheduler.py @@ -330,14 +330,7 @@ class Scheduler(PollScheduler): if not (isinstance(task, Package) and \ task.operation == "merge"): continue - try: - properties = flatten(use_reduce(paren_reduce( - task.metadata["PROPERTIES"]), uselist=task.use.enabled)) - except portage.exception.InvalidDependString, e: - show_invalid_depstring_notice(task, - task.metadata["PROPERTIES"], str(e)) - raise self._unknown_internal_error() - if "interactive" in properties: + if 'interactive' in task.metadata.properties: interactive_tasks.append(task) return interactive_tasks diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index b19dbb1b6..515bac2fe 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -3711,18 +3711,8 @@ class depgraph(object): else: repo_path_real = portdb.getRepositoryPath(repo_name) pkg_use = list(pkg.use.enabled) - try: - restrict = flatten(use_reduce(paren_reduce( - pkg.metadata["RESTRICT"]), uselist=pkg_use)) - except portage.exception.InvalidDependString, e: - if not pkg.installed: - show_invalid_depstring_notice(x, - pkg.metadata["RESTRICT"], str(e)) - del e - return 1 - restrict = [] - if "ebuild" == pkg_type and x[3] != "nomerge" and \ - "fetch" in restrict: + if not pkg.built and pkg.operation == 'merge' and \ + 'fetch' in pkg.metadata.restrict: fetch = red("F") if ordered: counters.restrict_fetch += 1 @@ -4009,18 +3999,8 @@ class depgraph(object): else: return colorize("PKG_NOMERGE", pkg_str) - try: - properties = flatten(use_reduce(paren_reduce( - pkg.metadata["PROPERTIES"]), uselist=pkg.use.enabled)) - except portage.exception.InvalidDependString, e: - if not pkg.installed: - show_invalid_depstring_notice(pkg, - pkg.metadata["PROPERTIES"], str(e)) - del e - return 1 - properties = [] - interactive = "interactive" in properties - if interactive and pkg.operation == "merge": + if 'interactive' in pkg.metadata.properties and \ + pkg.operation == 'merge': addl = colorize("WARN", "I") + addl[1:] if ordered: counters.interactive += 1 @@ -4912,6 +4892,9 @@ def get_masking_status(pkg, pkgsettings, root_config): if not pkgsettings._accept_chost(pkg.cpv, pkg.metadata): mreasons.append("CHOST: %s" % \ pkg.metadata["CHOST"]) + if pkg.invalid: + for msg in pkg.invalid: + mreasons.append("invalid: %s" % (msg,)) if pkg.built and not pkg.installed: if not "EPREFIX" in pkg.metadata or not pkg.metadata["EPREFIX"]: diff --git a/pym/_emerge/visible.py b/pym/_emerge/visible.py index e47089ed4..87f5db640 100644 --- a/pym/_emerge/visible.py +++ b/pym/_emerge/visible.py @@ -22,6 +22,8 @@ def visible(pkgsettings, pkg): if not pkg.metadata["SLOT"]: return False if not pkg.installed: + if pkg.invalid: + return False if not pkgsettings._accept_chost(pkg.cpv, pkg.metadata): return False if pkg.built and not pkg.installed: diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 7623a58b7..307574b35 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -1209,6 +1209,7 @@ class config(object): self.uvlist = [] self._accept_chost_re = None self._accept_license = None + self._accept_license_str = None self.virtuals = {} self.virts_p = {} @@ -2876,17 +2877,19 @@ class config(object): # ACCEPT_LICENSE is a lazily evaluated incremental, so that * can be # used to match all licenses without every having to explicitly expand # it to all licenses. - if self._accept_license is None: - if self.local_config: - mysplit = [] - for curdb in mydbs: - mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split()) - if mysplit: - self.configlist[-1]['ACCEPT_LICENSE'] = ' '.join(mysplit) + if self.local_config: + mysplit = [] + for curdb in mydbs: + mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split()) + accept_license_str = ' '.join(mysplit) + if accept_license_str: + self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str + if accept_license_str != self._accept_license_str: + self._accept_license_str = accept_license_str self._accept_license = tuple(self.expandLicenseTokens(mysplit)) - else: - # repoman will accept any license - self._accept_license = () + else: + # repoman will accept any license + self._accept_license = () for mykey in myincrementals: diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index db6e36fcd..abd6cc870 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -50,7 +50,7 @@ class dbapi(object): pass def cp_list(self, cp, use_cache=1): - return + raise NotImplementedError(self) def _cpv_sort_ascending(self, cpv_list): """ -- 2.26.2