diff options
Diffstat (limited to 'engine/SCons/Util.py')
| -rw-r--r-- | engine/SCons/Util.py | 158 | 
1 files changed, 78 insertions, 80 deletions
diff --git a/engine/SCons/Util.py b/engine/SCons/Util.py index c9aa2b5..476f5d8 100644 --- a/engine/SCons/Util.py +++ b/engine/SCons/Util.py @@ -3,7 +3,7 @@  Various utility functions go here.  """  # -# Copyright (c) 2001 - 2017 The SCons Foundation +# Copyright (c) 2001 - 2019 The SCons Foundation  #  # Permission is hereby granted, free of charge, to any person obtaining  # a copy of this software and associated documentation files (the @@ -24,7 +24,7 @@ Various utility functions go here.  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "src/engine/SCons/Util.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog" +__revision__ = "src/engine/SCons/Util.py a56bbd8c09fb219ab8a9673330ffcd55279219d0 2019-03-26 23:16:31 bdeegan"  import os  import sys @@ -37,21 +37,18 @@ import pprint  PY3 = sys.version_info[0] == 3  try: +    from collections import UserDict, UserList, UserString +except ImportError:      from UserDict import UserDict -except ImportError as e: -    from collections import UserDict - -try:      from UserList import UserList -except ImportError as e: -    from collections import UserList - -from collections import Iterable +    from UserString import UserString  try: -    from UserString import UserString -except ImportError as e: -    from collections import UserString +    from collections.abc import Iterable, MappingView +except ImportError: +    from collections import Iterable + +from collections import OrderedDict  # Don't "from types import ..." these because we need to get at the  # types module later to look for UnicodeType. @@ -63,7 +60,7 @@ MethodType      = types.MethodType  FunctionType    = types.FunctionType  try: -    unicode +    _ = type(unicode)  except NameError:      UnicodeType = str  else: @@ -106,7 +103,7 @@ def containsOnly(str, set):      return 1  def splitext(path): -    "Same as os.path.splitext() but faster." +    """Same as os.path.splitext() but faster."""      sep = rightmost_separator(path, os.sep)      dot = path.rfind('.')      # An ext is only real if it has at least one non-digit char @@ -371,7 +368,13 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited=None):  DictTypes = (dict, UserDict)  ListTypes = (list, UserList) -SequenceTypes = (list, tuple, UserList) + +try: +    # Handle getting dictionary views. +    SequenceTypes = (list, tuple, UserList, MappingView) +except NameError: +    SequenceTypes = (list, tuple, UserList) +  # Note that profiling data shows a speed-up when comparing  # explicitly with str and unicode instead of simply comparing @@ -1029,64 +1032,9 @@ class CLVar(UserList):          return UserList.__add__(self, CLVar(other))      def __radd__(self, other):          return UserList.__radd__(self, CLVar(other)) -    def __coerce__(self, other): -        return (self, CLVar(other))      def __str__(self):          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: -#     http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747 -# Including fixes/enhancements from the follow-on discussions. -class OrderedDict(UserDict): -    def __init__(self, dict = None): -        self._keys = [] -        UserDict.__init__(self, dict) - -    def __delitem__(self, key): -        UserDict.__delitem__(self, key) -        self._keys.remove(key) - -    def __setitem__(self, key, item): -        UserDict.__setitem__(self, key, item) -        if key not in self._keys: self._keys.append(key) - -    def clear(self): -        UserDict.clear(self) -        self._keys = [] - -    def copy(self): -        dict = OrderedDict() -        dict.update(self) -        return dict - -    def items(self): -        return list(zip(self._keys, list(self.values()))) - -    def keys(self): -        return self._keys[:] - -    def popitem(self): -        try: -            key = self._keys[-1] -        except IndexError: -            raise KeyError('dictionary is empty') - -        val = self[key] -        del self[key] - -        return (key, val) - -    def setdefault(self, key, failobj = None): -        UserDict.setdefault(self, key, failobj) -        if key not in self._keys: self._keys.append(key) - -    def update(self, dict): -        for (key, val) in dict.items(): -            self.__setitem__(key, val) - -    def values(self): -        return list(map(self.get, self._keys))  class Selector(OrderedDict):      """A callable ordered dictionary that maps file suffixes to @@ -1428,8 +1376,8 @@ def make_path_relative(path):  # The original idea for AddMethod() and RenameFunction() come from the  # following post to the ActiveState Python Cookbook:  # -#	ASPN: Python Cookbook : Install bound methods in an instance -#	http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/223613 +#   ASPN: Python Cookbook : Install bound methods in an instance +#   http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/223613  #  # That code was a little fragile, though, so the following changes  # have been wrung on it: @@ -1446,8 +1394,8 @@ def make_path_relative(path):  #   the "new" module, as alluded to in Alex Martelli's response to the  #   following Cookbook post:  # -#	ASPN: Python Cookbook : Dynamically added methods to a class -#	http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732 +#   ASPN: Python Cookbook : Dynamically added methods to a class +#   http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732  def AddMethod(obj, function, name=None):      """ @@ -1517,6 +1465,11 @@ else:          md5 = True          def MD5signature(s): +            """ +            Generate a String of Hex digits representing the md5 signature of the string +            :param s: either string or bytes. Normally should be bytes +            :return: String of hex digits +            """              m = hashlib.md5()              try: @@ -1527,6 +1480,11 @@ else:              return m.hexdigest()          def MD5filesignature(fname, chunksize=65536): +            """ +            :param fname: +            :param chunksize: +            :return: String of Hex digits +            """              m = hashlib.md5()              f = open(fname, "rb")              while True: @@ -1537,6 +1495,7 @@ else:              f.close()              return m.hexdigest() +  def MD5collect(signatures):      """      Collects a list of signatures into an aggregate signature. @@ -1609,19 +1568,27 @@ class NullSeq(Null):  del __revision__ -def to_bytes (s): + +def to_bytes(s): +    if s is None: +        return b'None' +    if not PY3 and isinstance(s, UnicodeType): +        # PY2, must encode unicode +        return bytearray(s, 'utf-8')      if isinstance (s, (bytes, bytearray)) or bytes is str: +        # Above case not covered here as py2 bytes and strings are the same          return s -    return bytes (s, 'utf-8') +    return bytes(s, 'utf-8') + -def to_str (s): +def to_str(s): +    if s is None: +        return 'None'      if bytes is str or is_String(s):          return s      return str (s, 'utf-8') - -# No cmp in py3, so we'll define it.  def cmp(a, b):      """      Define cmp because it's no longer available in python3 @@ -1630,6 +1597,37 @@ def cmp(a, b):      return (a > b) - (a < b) +def get_env_bool(env, name, default=False): +    """Get a value of env[name] converted to boolean. The value of env[name] is +    interpreted as follows: 'true', 'yes', 'y', 'on' (case insensitive) and +    anything convertible to int that yields non-zero integer are True values; +    '0', 'false', 'no', 'n' and 'off' (case insensitive) are False values. For +    all other cases, default value is returned. + +    :Parameters: +        - `env`     - dict or dict-like object, a convainer with variables +        - `name`    - name of the variable in env to be returned +        - `default` - returned when env[name] does not exist or can't be converted to bool +    """ +    try: +        var = env[name] +    except KeyError: +        return default +    try: +        return bool(int(var)) +    except ValueError: +        if str(var).lower() in ('true', 'yes', 'y', 'on'): +            return True +        elif str(var).lower() in ('false', 'no', 'n', 'off'): +            return False +        else: +            return default + + +def get_os_env_bool(name, default=False): +    """Same as get_env_bool(os.environ, name, default).""" +    return get_env_bool(os.environ, name, default) +  # Local Variables:  # tab-width:4  # indent-tabs-mode:nil  | 
