From 7c651e273c4db37f4babd91aaecf26800c50dd79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Thu, 28 Sep 2017 10:21:20 +0200 Subject: New upstream version 3.0.0 --- engine/SCons/Util.py | 256 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 181 insertions(+), 75 deletions(-) (limited to 'engine/SCons/Util.py') diff --git a/engine/SCons/Util.py b/engine/SCons/Util.py index 2370a9c..2a1604b 100644 --- a/engine/SCons/Util.py +++ b/engine/SCons/Util.py @@ -3,7 +3,7 @@ Various utility functions go here. """ # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 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,24 +24,50 @@ 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 rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" +__revision__ = "src/engine/SCons/Util.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" import os import sys import copy import re import types +import codecs +import pprint -from collections import UserDict, UserList, UserString +PY3 = sys.version_info[0] == 3 + +try: + 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 + +try: + from UserString import UserString +except ImportError as e: + from collections import UserString # Don't "from types import ..." these because we need to get at the # types module later to look for UnicodeType. -InstanceType = types.InstanceType + +# Below not used? +# InstanceType = types.InstanceType + MethodType = types.MethodType FunctionType = types.FunctionType -try: unicode -except NameError: UnicodeType = None -else: UnicodeType = unicode + +try: + unicode +except NameError: + UnicodeType = str +else: + UnicodeType = unicode def dictify(keys, values, result={}): for k, v in zip(keys, values): @@ -111,9 +137,28 @@ class NodeList(UserList): >>> someList.strip() [ 'foo', 'bar' ] """ + +# def __init__(self, initlist=None): +# self.data = [] +# # print("TYPE:%s"%type(initlist)) +# if initlist is not None: +# # XXX should this accept an arbitrary sequence? +# if type(initlist) == type(self.data): +# self.data[:] = initlist +# elif isinstance(initlist, (UserList, NodeList)): +# self.data[:] = initlist.data[:] +# elif isinstance(initlist, Iterable): +# self.data = list(initlist) +# else: +# self.data = [ initlist,] + + def __nonzero__(self): return len(self.data) != 0 + def __bool__(self): + return self.__nonzero__() + def __str__(self): return ' '.join(map(str, self.data)) @@ -128,6 +173,25 @@ class NodeList(UserList): result = [getattr(x, name) for x in self.data] return self.__class__(result) + def __getitem__(self, index): + """ + This comes for free on py2, + but py3 slices of NodeList are returning a list + breaking slicing nodelist and refering to + properties and methods on contained object + """ +# return self.__class__(self.data[index]) + + if isinstance(index, slice): + # Expand the slice object using range() + # limited by number of items in self.data + indices = index.indices(len(self.data)) + return self.__class__([self[x] for x in + range(*indices)]) + else: + # Return one item of the tart + return self.data[index] + _get_env_var = re.compile(r'^\$([_a-zA-Z]\w*|{[_a-zA-Z]\w*})$') @@ -153,7 +217,7 @@ class DisplayEngine(object): return if append_newline: text = text + '\n' try: - sys.stdout.write(unicode(text)) + sys.stdout.write(UnicodeType(text)) except IOError: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed @@ -167,16 +231,17 @@ class DisplayEngine(object): def set_mode(self, mode): self.print_it = mode + def render_tree(root, child_func, prune=0, margin=[0], visited=None): """ Render a tree of nodes into an ASCII tree view. - root - the root node of the tree - child_func - the function called to get the children of a node - prune - don't visit the same node twice - margin - the format of the left margin to use for children of root. - 1 results in a pipe, and 0 results in no pipe. - visited - a dictionary of visited nodes in the current branch if not prune, - or in the whole tree if prune. + + :Parameters: + - `root`: the root node of the tree + - `child_func`: the function called to get the children of a node + - `prune`: don't visit the same node twice + - `margin`: the format of the left margin to use for children of root. 1 results in a pipe, and 0 results in no pipe. + - `visited`: a dictionary of visited nodes in the current branch if not prune, or in the whole tree if prune. """ rname = str(root) @@ -202,33 +267,33 @@ def render_tree(root, child_func, prune=0, margin=[0], visited=None): visited[rname] = 1 for i in range(len(children)): - margin.append(i (3, 2): + method = MethodType(function, obj) + else: + method = MethodType(function, obj, obj.__class__) else: - # "obj" is a class, so it gets an unbound method. - setattr(obj, name, MethodType(function, None, obj)) + # Handle classes + method = function + + setattr(obj, name, method) def RenameFunction(function, name): """ Returns a function identical to the specified function, but with the specified name. """ - return FunctionType(function.func_code, - function.func_globals, + return FunctionType(function.__code__, + function.__globals__, name, - function.func_defaults) + function.__defaults__) md5 = False + + def MD5signature(s): return str(s) + def MD5filesignature(fname, chunksize=65536): - f = open(fname, "rb") - result = f.read() - f.close() + with open(fname, "rb") as f: + result = f.read() return result try: @@ -1430,9 +1518,15 @@ except ImportError: else: if hasattr(hashlib, 'md5'): md5 = True + def MD5signature(s): m = hashlib.md5() - m.update(str(s)) + + try: + m.update(to_bytes(s)) + except TypeError as e: + m.update(to_bytes(str(s))) + return m.hexdigest() def MD5filesignature(fname, chunksize=65536): @@ -1442,10 +1536,10 @@ else: blck = f.read(chunksize) if not blck: break - m.update(str(blck)) + m.update(to_bytes(blck)) f.close() return m.hexdigest() - + def MD5collect(signatures): """ Collects a list of signatures into an aggregate signature. @@ -1494,6 +1588,8 @@ class Null(object): return "Null(0x%08X)" % id(self) def __nonzero__(self): return False + def __bool__(self): + return False def __getattr__(self, name): return self def __setattr__(self, name, value): @@ -1516,6 +1612,16 @@ class NullSeq(Null): del __revision__ +def to_bytes (s): + if isinstance (s, (bytes, bytearray)) or bytes is str: + return s + return bytes (s, 'utf-8') + +def to_str (s): + if bytes is str or is_String(s): + return s + return str (s, 'utf-8') + # Local Variables: # tab-width:4 # indent-tabs-mode:nil -- cgit v1.2.3