From b23b4d35022643e3a2d5f911a91a6081ca2f6424 Mon Sep 17 00:00:00 2001 From: Brian Harring Date: Tue, 9 Aug 2005 07:53:33 +0000 Subject: broke the conditional node class out into portage.package.conditionals.base, and updated portage.ebuild.conditionals pydoc documentation also... --- portage/ebuild/conditionals.py | 49 +++++++++---------------- portage/package/conditionals.py | 79 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 portage/package/conditionals.py diff --git a/portage/ebuild/conditionals.py b/portage/ebuild/conditionals.py index 67c2b6c..090cdaf 100644 --- a/portage/ebuild/conditionals.py +++ b/portage/ebuild/conditionals.py @@ -1,53 +1,32 @@ # Copyright: 2005 Gentoo Foundation # Author(s): Jason Stubbs (jstubbs@gentoo.org), Brian Harring (ferringb@gentoo.org) # License: GPL2 -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/conditionals.py,v 1.3 2005/08/03 00:27:14 ferringb Exp $ +# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/conditionals.py,v 1.4 2005/08/09 07:53:33 ferringb Exp $ # TODO: move exceptions elsewhere, bind them to a base exception for portage import logging from portage.restrictions.restrictionSet import RestrictionSet, OrRestrictionSet from portage.util.strings import iter_tokens +from portage.package.conditionals import base as Conditional -class base(object): - """base object representing a conditional node""" - -class Conditional(base): - - def __init__(self, node, payload): - if node[0] == "!": - self.negate = True - self.cond = node[1:] - else: - self.negate = False - self.cond = node - self.restrictions = payload - - - def __str__(self): - if self.negate: s="!"+self.cond - else: s=self.cond - try: s2=" ".join(self.restrictions) - except TypeError: - s2=str(self.restrictions) - return "%s? ( %s )" % (s, s2) - - - def __iter__(self): - return iter(self.restrictions) - +def conditional_converter(node, payload): + if node[0] == "!": + return Conditional(node[1:], payload, negate=True) + return Conditional(node, payload) + class DepSet(RestrictionSet): __slots__ = tuple(["has_conditionals", "conditional_class"] + list(RestrictionSet.__slots__)) def __init__(self, dep_str, element_func, operators={"||":OrRestrictionSet}, \ - conditional_class=Conditional, empty=False): + conditional_converter=conditional_converter, conditional_class=Conditional, empty=False): """dep_str is a dep style syntax, element_func is a callable returning the obj for each element, and cleanse_string controls whether or translation of tabs/newlines is required""" super(DepSet, self).__init__() self.conditional_class = conditional_class - + if empty: return # anyone who uses this routine as fodder for pushing a rewrite in lisp I reserve the right to deliver an @@ -65,7 +44,7 @@ class DepSet(RestrictionSet): if len(depsets[-1].restrictions) == 0: raise ParseError(dep_str) elif conditionals[-1].endswith('?'): - depsets[-2].restrictions.append(conditional_class(conditionals.pop(-1)[:-1], depsets[-1])) + depsets[-2].restrictions.append(conditional_converter(conditionals.pop(-1)[:-1], depsets[-1])) else: depsets[-2].restrictions.append(operators[conditionals.pop(-1)](depsets[-1])) if not has_conditionals[-2]: @@ -82,7 +61,8 @@ class DepSet(RestrictionSet): raise ParseError(dep_str) # push another frame on - depsets.append(self.__class__(None, element_func, empty=True, conditional_class=self.conditional_class)) + depsets.append(self.__class__(None, element_func, empty=True, conditional_converter=conditional_converter, + conditional_class=self.conditional_class)) conditionals.append(k) if k.endswith("?"): has_conditionals[-1] = True @@ -115,7 +95,10 @@ class DepSet(RestrictionSet): while len(stack) != 0: for node in stack[0]: if isinstance(node, self.conditional_class): - if cond_dict.get(node.cond, False) ^ node.negate: + if node.cond in cond_dict: + if not node.negate: + stack.append(node.restrictions) + elif node.negate: stack.append(node.restrictions) else: flat_deps.restrictions.append(node) diff --git a/portage/package/conditionals.py b/portage/package/conditionals.py new file mode 100644 index 0000000..e17fc6b --- /dev/null +++ b/portage/package/conditionals.py @@ -0,0 +1,79 @@ +# Copyright: 2005 Gentoo Foundation +# Author(s): Brian Harring (ferringb@gentoo.org) +# License: GPL2 +# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/package/conditionals.py,v 1.1 2005/08/09 07:53:33 ferringb Exp $ + +#from metadata import package as package_base +from portage.util.mappings import LimitedChangeSet + +class base(object): + """base object representing a conditional node""" + + def __init__(self, node, payload, negate=False): + self.negate, self.cond, self.restrictions = negate, node, payload + + def __str__(self): + if self.negate: s="!"+self.cond + else: s=self.cond + try: s2=" ".join(self.restrictions) + except TypeError: + s2=str(self.restrictions) + return "%s? ( %s )" % (s, s2) + + + def __iter__(self): + return iter(self.restrictions) + +class PackageWrapper(object): + def __init__(self, pkg_instance, configurable_attribute_name, initial_settings=[], unchangable_settings=[], attributes_to_wrap={}): + """pkg_instance should be an existing package instance + configurable_attribute_name is the attribute name to fake on this instance for accessing builtup conditional changes + use, fex, is valid for unconfigured ebuilds + + initial_settings is the initial settings of this beast, dict + attributes_to_wrap should be a dict of attr_name:callable + the callable receives the 'base' attribute (unconfigured), with the built up conditionals as a second arg + """ + self.__wrapped_pkg = pkg_instance + self.__wrapped_attr = attributes_to_wrap + if configurable_attribute_name.find(".") != -1: + raise ValueError("can only wrap first level attributes, 'obj.dar' fex, not '%s'" % (configurable_attribute_name)) + setattr(self, configurable_attribute_name, LimitedChangeSet(initial_settings, unchangable_settings)) + self.__configurable = getattr(self, configurable_attribute_name) + self.__reuse_pt = 0 + self.__cached_wrapped = {} + + def rollback(self, point=0): + self.__configurable.rollback(point) + # yes, nuking objs isn't necessarily required. easier this way though. + # XXX: optimization point + self.__reuse_pt += 1 + + def commit(self): + self.__configurable.commit() + + def changes_count(self): + return self.__configurable.changes_count() + + def push_add(self, key): + if key not in self.__configurable: + self.__configurable.add(key) + self.__reuse_pt += 1 + + def push_remove(self, key): + if key in self.__configurable: + self.__configurable.remove(key) + self.__reuse_pt += 1 + + def __getattr__(self, attr): + if attr in self.__wrapped_attr: + if attr in self.__cached_wrapped: + if self.__cached_wrapped[attr][0] == self.__reuse_pt: + return self.__cached_wrapped[attr][1] + del self.__cached_wrapped[attr] + o = self.__wrapped_attr[attr](getattr(self.__wrapped_pkg, attr), self.__configurable) + self.__cached_wrapped[attr] = (self.__reuse_pt, o) + return o + else: + return getattr(self.__wrapped_pkg, attr) + -- cgit v1.2.3-65-gdbad