Salome HOME
option compile --update
[tools/sat.git] / src / pyconf.py
index fa0b259b6ed711d63bb9a41ec95e0313b4d15a77..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.
@@ -621,12 +619,14 @@ class Mapping(Container):
                 skey = repr(key)
             if comment:
                 stream.write('%s#%s' % (indstr, comment))
+            if skey.startswith("u'"):
+                skey = skey[1:]
             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):
     """
@@ -644,7 +644,7 @@ class Config(Mapping):
             self.sys = sys
             self.os = os
 
-    def __init__(self, streamOrFile=None, parent=None):
+    def __init__(self, streamOrFile=None, parent=None, PWD = None):
         """
         Initializes an instance.
 
@@ -673,6 +673,13 @@ class Config(Mapping):
                 streamOrFile = streamOpener(streamOrFile)
             load = object.__getattribute__(self, "load")
             load(streamOrFile)
+            # Specific add for salomeTools : PWD
+            if PWD:
+                key, pwd = PWD
+                if key == "":
+                    self.PWD = pwd
+                else:
+                    self[key].PWD = pwd
 
     def load(self, stream):
         """
@@ -720,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.
@@ -730,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()
 
@@ -810,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:
@@ -833,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.
 
@@ -853,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.
@@ -875,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):
     """
@@ -1214,6 +1221,10 @@ class ConfigReader(object):
         else:
             self.lastc = None
         self.last_token = tt
+        
+        # Python 2.x specific unicode conversion
+        if sys.version_info[0] == 2 and tt == WORD and isinstance(token, unicode):
+            token = token.encode('ascii')
         return (tt, token)
 
     def load(self, stream, parent=None, suffix=None):
@@ -1513,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}.
@@ -1523,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]
@@ -1557,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