Move 2.0 changes collected in branches/pending back to trunk for further
[scons.git] / src / engine / SCons / Util.py
index 9e5fe38de19ff597e11ef0110f1f974dea42e70d..709cf1f0524b8888aa3884ff5c1367deea438dc8 100644 (file)
@@ -33,7 +33,6 @@ import copy
 import os
 import os.path
 import re
-import string
 import sys
 import types
 
@@ -59,11 +58,11 @@ if _altsep is None and sys.platform == 'win32':
     # My ActivePython 2.0.1 doesn't set os.altsep!  What gives?
     _altsep = '/'
 if _altsep:
-    def rightmost_separator(path, sep, _altsep=_altsep):
-        rfind = string.rfind
-        return max(rfind(path, sep), rfind(path, _altsep))
+    def rightmost_separator(path, sep):
+        return max(path.rfind(sep), path.rfind(_altsep))
 else:
-    rightmost_separator = string.rfind
+    def rightmost_separator(path, sep):
+        return path.rfind(sep)
 
 # First two from the Python Cookbook, just for completeness.
 # (Yeah, yeah, YAGNI...)
@@ -88,7 +87,7 @@ def containsOnly(str, set):
 def splitext(path):
     "Same as os.path.splitext() but faster."
     sep = rightmost_separator(path, os.sep)
-    dot = string.rfind(path, '.')
+    dot = path.rfind('.')
     # An ext is only real if it has at least one non-digit char
     if dot > sep and not containsOnly(path[dot:], "0123456789."):
         return path[:dot],path[dot:]
@@ -104,7 +103,7 @@ def updrive(path):
     """
     drive, rest = os.path.splitdrive(path)
     if drive:
-        path = string.upper(drive) + rest
+        path = drive.upper() + rest
     return path
 
 class NodeList(UserList):
@@ -121,20 +120,17 @@ class NodeList(UserList):
         return len(self.data) != 0
 
     def __str__(self):
-        return string.join(map(str, self.data))
+        return ' '.join(map(str, self.data))
 
     def __iter__(self):
         return iter(self.data)
 
     def __call__(self, *args, **kwargs):
-        result = map(lambda x, args=args, kwargs=kwargs: apply(x,
-                                                               args,
-                                                               kwargs),
-                     self.data)
+        result = [x(*args, **kwargs) for x in self.data]
         return self.__class__(result)
 
     def __getattr__(self, name):
-        result = map(lambda x, n=name: getattr(x, n), self.data)
+        result = [getattr(x, name) for x in self.data]
         return self.__class__(result)
 
 
@@ -204,7 +200,7 @@ def render_tree(root, child_func, prune=0, margin=[0], visited={}):
         else:
             retval = retval + "  "
 
-    if visited.has_key(rname):
+    if rname in visited:
         return retval + "+-[" + rname + "]\n"
 
     retval = retval + "+-" + rname + "\n"
@@ -273,15 +269,15 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}):
 
     def MMM(m):
         return ["  ","| "][m]
-    margins = map(MMM, margin[:-1])
+    margins = list(map(MMM, margin[:-1]))
 
     children = child_func(root)
 
-    if prune and visited.has_key(rname) and children:
-        print string.join(tags + margins + ['+-[', rname, ']'], '')
+    if prune and rname in visited and children:
+        print ''.join(tags + margins + ['+-[', rname, ']'])
         return
 
-    print string.join(tags + margins + ['+-', rname], '')
+    print ''.join(tags + margins + ['+-', rname])
 
     visited[rname] = 1
 
@@ -426,7 +422,7 @@ except TypeError:
 
     def to_String_for_subst(s):
         if is_Sequence( s ):
-            return string.join( map(to_String_for_subst, s) )
+            return ' '.join( map(to_String_for_subst, s) )
 
         return to_String( s )
 
@@ -543,7 +539,7 @@ else:
             return str(s)
 
     def to_String_for_subst(s, 
-                            isinstance=isinstance, join=string.join, str=str, to_String=to_String,
+                            isinstance=isinstance, str=str, to_String=to_String,
                             BaseStringTypes=BaseStringTypes, SequenceTypes=SequenceTypes,
                             UserString=UserString):
                             
@@ -554,7 +550,7 @@ else:
             l = []
             for e in s:
                 l.append(to_String_for_subst(e))
-            return join( s )
+            return ' '.join( s )
         elif isinstance(s, UserString):
             # s.data can only be either a unicode or a regular
             # string. Please see the UserString initializer.
@@ -602,7 +598,7 @@ def _semi_deepcopy_dict(x):
 d[types.DictionaryType] = _semi_deepcopy_dict
 
 def _semi_deepcopy_list(x):
-    return map(semi_deepcopy, x)
+    return list(map(semi_deepcopy, x))
 d[types.ListType] = _semi_deepcopy_list
 
 def _semi_deepcopy_tuple(x):
@@ -766,16 +762,16 @@ if sys.platform == 'win32':
             except KeyError:
                 return None
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         if pathext is None:
             try:
                 pathext = os.environ['PATHEXT']
             except KeyError:
                 pathext = '.COM;.EXE;.BAT;.CMD'
         if is_String(pathext):
-            pathext = string.split(pathext, os.pathsep)
+            pathext = pathext.split(os.pathsep)
         for ext in pathext:
-            if string.lower(ext) == string.lower(file[-len(ext):]):
+            if ext.lower() == file[-len(ext):].lower():
                 pathext = ['']
                 break
         if not is_List(reject) and not is_Tuple(reject):
@@ -801,11 +797,11 @@ elif os.name == 'os2':
             except KeyError:
                 return None
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         if pathext is None:
             pathext = ['.exe', '.cmd']
         for ext in pathext:
-            if string.lower(ext) == string.lower(file[-len(ext):]):
+            if ext.lower() == file[-len(ext):].lower():
                 pathext = ['']
                 break
         if not is_List(reject) and not is_Tuple(reject):
@@ -832,7 +828,7 @@ else:
             except KeyError:
                 return None
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         if not is_List(reject) and not is_Tuple(reject):
             reject = [reject]
         for d in path:
@@ -881,18 +877,18 @@ def PrependPath(oldpath, newpath, sep = os.pathsep,
     is_list = 1
     paths = orig
     if not is_List(orig) and not is_Tuple(orig):
-        paths = string.split(paths, sep)
+        paths = paths.split(sep)
         is_list = 0
 
     if is_String(newpath):
-        newpaths = string.split(newpath, sep)
+        newpaths = newpath.split(sep)
     elif not is_List(newpath) and not is_Tuple(newpath):
         newpaths = [ newpath ]  # might be a Dir
     else:
         newpaths = newpath
 
     if canonicalize:
-        newpaths=map(canonicalize, newpaths)
+        newpaths=list(map(canonicalize, newpaths))
 
     if not delete_existing:
         # First uniquify the old paths, making sure to 
@@ -934,7 +930,7 @@ def PrependPath(oldpath, newpath, sep = os.pathsep,
     if is_list:
         return paths
     else:
-        return string.join(paths, sep)
+        return sep.join(paths)
 
 def AppendPath(oldpath, newpath, sep = os.pathsep, 
                delete_existing=1, canonicalize=None):
@@ -962,18 +958,18 @@ def AppendPath(oldpath, newpath, sep = os.pathsep,
     is_list = 1
     paths = orig
     if not is_List(orig) and not is_Tuple(orig):
-        paths = string.split(paths, sep)
+        paths = paths.split(sep)
         is_list = 0
 
     if is_String(newpath):
-        newpaths = string.split(newpath, sep)
+        newpaths = newpath.split(sep)
     elif not is_List(newpath) and not is_Tuple(newpath):
         newpaths = [ newpath ]  # might be a Dir
     else:
         newpaths = newpath
 
     if canonicalize:
-        newpaths=map(canonicalize, newpaths)
+        newpaths=list(map(canonicalize, newpaths))
 
     if not delete_existing:
         # add old paths to result, then
@@ -1015,13 +1011,13 @@ def AppendPath(oldpath, newpath, sep = os.pathsep,
     if is_list:
         return paths
     else:
-        return string.join(paths, sep)
+        return sep.join(paths)
 
 if sys.platform == 'cygwin':
     def get_native_path(path):
         """Transforms an absolute path into a native path for the system.  In
         Cygwin, this converts from a Cygwin path to a Windows one."""
-        return string.replace(os.popen('cygpath -w ' + path).read(), '\n', '')
+        return os.popen('cygpath -w ' + path).read().replace('\n', '')
 else:
     def get_native_path(path):
         """Transforms an absolute path into a native path for the system.
@@ -1034,7 +1030,7 @@ def Split(arg):
     if is_List(arg) or is_Tuple(arg):
         return arg
     elif is_String(arg):
-        return string.split(arg)
+        return arg.split()
     else:
         return [arg]
 
@@ -1057,7 +1053,7 @@ class CLVar(UserList):
     def __coerce__(self, other):
         return (self, CLVar(other))
     def __str__(self):
-        return string.join(self.data)
+        return ' '.join(self.data)
 
 # A dictionary that preserves the order in which items are added.
 # Submitted by David Benjamin to ActiveState's Python Cookbook web site:
@@ -1111,7 +1107,7 @@ class OrderedDict(UserDict):
             self.__setitem__(key, val)
 
     def values(self):
-        return map(self.get, self._keys)
+        return list(map(self.get, self._keys))
 
 class Selector(OrderedDict):
     """A callable ordered dictionary that maps file suffixes to
@@ -1132,7 +1128,7 @@ class Selector(OrderedDict):
             for (k,v) in self.items():
                 if k is not None:
                     s_k = env.subst(k)
-                    if s_dict.has_key(s_k):
+                    if s_k in s_dict:
                         # We only raise an error when variables point
                         # to the same suffix.  If one suffix is literal
                         # and a variable suffix contains this literal,
@@ -1279,7 +1275,7 @@ def uniquer_hashables(seq):
     result = []
     for item in seq:
         #if not item in seen:
-        if not seen.has_key(item):
+        if item not in seen:
             seen[item] = 1
             result.append(item)
     return result
@@ -1304,7 +1300,7 @@ class LogicalLines:
             else:
                 result.append(line)
                 break
-        return string.join(result, '')
+        return ''.join(result)
 
     def readlines(self):
         result = []
@@ -1402,8 +1398,7 @@ class UniqueList(UserList):
         UserList.reverse(self)
     def sort(self, *args, **kwds):
         self.__make_unique()
-        #return UserList.sort(self, *args, **kwds)
-        return apply(UserList.sort, (self,)+args, kwds)
+        return UserList.sort(self, *args, **kwds)
     def extend(self, other):
         UserList.extend(self, other)
         self.unique = False
@@ -1568,7 +1563,7 @@ def MD5collect(signatures):
     if len(signatures) == 1:
         return signatures[0]
     else:
-        return MD5signature(string.join(signatures, ', '))
+        return MD5signature(', '.join(signatures))
 
 
 
@@ -1605,8 +1600,7 @@ class Null:
     """ Null objects always and reliably "do nothing." """
     def __new__(cls, *args, **kwargs):
         if not '_inst' in vars(cls):
-            #cls._inst = type.__new__(cls, *args, **kwargs)
-            cls._inst = apply(type.__new__, (cls,) + args, kwargs)
+            cls._inst = type.__new__(cls, *args, **kwargs)
         return cls._inst
     def __init__(self, *args, **kwargs):
         pass