Salome HOME
specialisation des paquets systemes par distribution, pour mieux gerer les differences
[tools/sat.git] / src / pyconf.py
index 713e3fe3e3e1e19d1a499317f5fcf193f8793eb1..5957d6ddcf8a12cbe2d5d971bf3eac266ca50ada 100644 (file)
@@ -276,7 +276,7 @@ class ConfigOutputStream(object):
         self.stream.close()
 
 def defaultStreamOpener(name):
-    """
+    """\
     This function returns a read-only stream, given its name. The name passed
     in should correspond to an existing stream, otherwise an exception will be
     raised.
@@ -343,25 +343,20 @@ def isWord(s):
     return s.isalnum()
 
 def makePath(prefix, suffix):
-    """
+    """\
     Make a path from a prefix and suffix.
 
-    Examples::
-
-        makePath('', 'suffix') -> 'suffix'
-        makePath('prefix', 'suffix') -> 'prefix.suffix'
-        makePath('prefix', '[1]') -> 'prefix[1]'
-
-    @param prefix:  The prefix to use. If it evaluates as false, the suffix
-                    is returned.
-    @type prefix:   str
-    @param suffix:  The suffix to use. It is either an identifier or an
-                    index in brackets.
-    @type suffix:   str
-    @return:        The path concatenation of prefix and suffix, with a
-                    dot if the suffix is not a bracketed index.
-    @rtype:         str
+    Examples:
+    makePath('', 'suffix') -> 'suffix'
+    makePath('prefix', 'suffix') -> 'prefix.suffix'
+    makePath('prefix', '[1]') -> 'prefix[1]'
 
+    @param prefix: The prefix to use. If it evaluates as false, the suffix is returned.
+    @type prefix: str
+    @param suffix: The suffix to use. It is either an identifier or an index in brackets.
+    @type suffix: str
+    @return: The path concatenation of prefix and suffix, with adot if the suffix is not a bracketed index.
+    @rtype: str
     """
     if not prefix:
         rv = suffix
@@ -421,7 +416,7 @@ class Container(object):
             item = item.evaluate(self)
         return item
 
-    def writeToStream(self, stream, indent, container):
+    def writeToStream(self, stream, indent, container, evaluated=False):
         """
         Write this instance to a stream at the specified indentation level.
 
@@ -437,13 +432,16 @@ class Container(object):
         """
         raise NotImplementedError
 
-    def writeValue(self, value, stream, indent):
+    def writeValue(self, value, stream, indent, evaluated=False):
         if isinstance(self, Mapping):
             indstr = ' '
         else:
             indstr = indent * '  '
         if isinstance(value, Reference) or isinstance(value, Expression):
-            stream.write('%s%r%s' % (indstr, value, NEWLINE))
+            if not evaluated:
+                stream.write('%s%r%s' % (indstr, value, NEWLINE))
+            else:
+                stream.write('%s%r%s' % (indstr, self.evaluate(value), NEWLINE))
         else:
             if isinstance(value, str): # and not isWord(value):
                 value = repr(value)
@@ -483,7 +481,7 @@ class Mapping(Container):
     def __getitem__(self, key):
         data = object.__getattribute__(self, 'data')
         if key not in data:
-            raise AttributeError(key)
+            raise AttributeError("Unknown pyconf key: '%s'" % key)
         rv = data[key]
         return self.evaluate(rv)
 
@@ -498,7 +496,7 @@ class Mapping(Container):
         #if name == "__class__":
         #    return ''
         data = object.__getattribute__(self, "data")
-        useData = data.has_key(name)
+        useData = name in data
         if useData:
             rv = getattr(data, name)
         else:
@@ -578,7 +576,7 @@ class Mapping(Container):
         order = object.__getattribute__(self, 'order')
         return order.__iter__()
 
-    def writeToStream(self, stream, indent, container):
+    def writeToStream(self, stream, indent, container, evaluated=False):
         """
         Write this instance to a stream at the specified indentation level.
 
@@ -598,10 +596,10 @@ class Mapping(Container):
             if isinstance(container, Mapping):
                 stream.write(NEWLINE)
             stream.write('%s{%s' % (indstr, NEWLINE))
-            self.__save__(stream, indent + 1)
+            self.__save__(stream, indent + 1, evaluated=evaluated)
             stream.write('%s}%s' % (indstr, NEWLINE))
 
-    def __save__(self, stream, indent=0):
+    def __save__(self, stream, indent=0, evaluated=False):
         """
         Save this configuration to the specified stream.
         @param stream: A stream to which the configuration is written.
@@ -626,9 +624,9 @@ class Mapping(Container):
             stream.write('%s%-*s :' % (indstr, maxlen, skey))
             value = data[key]
             if isinstance(value, Container):
-                value.writeToStream(stream, indent, self)
+                value.writeToStream(stream, indent, self, evaluated=evaluated)
             else:
-                self.writeValue(value, stream, indent)
+                self.writeValue(value, stream, indent, evaluated=evaluated)
 
 class Config(Mapping):
     """
@@ -729,7 +727,7 @@ class Config(Mapping):
         else:
             delattr(namespaces[0], name)
 
-    def __save__(self, stream, indent=0, no_close=False):
+    def __save__(self, stream, indent=0, no_close=False, evaluated=False):
         """
         Save this configuration to the specified stream. The stream is
         closed if this is the top-level configuration in the hierarchy.
@@ -739,7 +737,7 @@ class Config(Mapping):
         @param indent: The indentation level for the output.
         @type indent: int
         """
-        Mapping.__save__(self, stream, indent)
+        Mapping.__save__(self, stream, indent, evaluated=evaluated)
         if indent == 0 and not no_close:
             stream.close()
 
@@ -819,7 +817,7 @@ class Sequence(Container):
         try:
             rv = data[index]
         except (IndexError, KeyError, TypeError):
-            raise ConfigResolutionError('%r is not a valid index for %r' % (index, object.__getattribute__(self, 'path')))
+            raise ConfigResolutionError('Invalid pyconf index %r for %r' % (index, object.__getattribute__(self, 'path')))
         if not isinstance(rv, list):
             rv = self.evaluate(rv)
         else:
@@ -842,7 +840,7 @@ class Sequence(Container):
     def __len__(self):
         return len(object.__getattribute__(self, 'data'))
 
-    def writeToStream(self, stream, indent, container):
+    def writeToStream(self, stream, indent, container, evaluated=False):
         """
         Write this instance to a stream at the specified indentation level.
 
@@ -862,10 +860,10 @@ class Sequence(Container):
             if isinstance(container, Mapping):
                 stream.write(NEWLINE)
             stream.write('%s[%s' % (indstr, NEWLINE))
-            self.__save__(stream, indent + 1)
+            self.__save__(stream, indent + 1, evaluated=evaluated)
             stream.write('%s]%s' % (indstr, NEWLINE))
 
-    def __save__(self, stream, indent):
+    def __save__(self, stream, indent, evaluated=False):
         """
         Save this instance to the specified stream.
         @param stream: A stream to which the configuration is written.
@@ -884,9 +882,9 @@ class Sequence(Container):
             if comment:
                 stream.write('%s#%s' % (indstr, comment))
             if isinstance(value, Container):
-                value.writeToStream(stream, indent, self)
+                value.writeToStream(stream, indent, self, evaluated=evaluated)
             else:
-                self.writeValue(value, stream, indent)
+                self.writeValue(value, stream, indent, evaluated=evaluated)
 
 class Reference(object):
     """
@@ -1526,9 +1524,9 @@ RCURLY, COMMA, found %r"
             ref.addElement(LBRACK, tv)
 
 def defaultMergeResolve(map1, map2, key):
-    """
-    A default resolver for merge conflicts. Returns a string
-    indicating what action to take to resolve the conflict.
+    """\
+    A default resolver for merge conflicts. 
+    Returns a string indicating what action to take to resolve the conflict.
 
     @param map1: The map being merged into.
     @type map1: L{Mapping}.
@@ -1536,11 +1534,13 @@ def defaultMergeResolve(map1, map2, key):
     @type map2: L{Mapping}.
     @param key: The key in map2 (which also exists in map1).
     @type key: str
+
     @return: One of "merge", "append", "mismatch" or "overwrite"
              indicating what action should be taken. This should
              be appropriate to the objects being merged - e.g.
              there is no point returning "merge" if the two objects
              are instances of L{Sequence}.
+
     @rtype: str
     """
     obj1 = map1[key]
@@ -1570,6 +1570,12 @@ def overwriteMergeResolve(map1, map2, key):
         rv = "overwrite"
     return rv
 
+def deepCopyMapping(inMapping):
+    res = Mapping()
+    for element in inMapping:
+        res[element] = inMapping[element]
+    return res
+
 class ConfigMerger(object):
     """
     This class is used for merging two configurations. If a key exists in the