Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: infra/services/gnumbd/support/util.py

Issue 355153002: Refactor infra git libs and testing. (Closed) Base URL: https://chromium.googlesource.com/infra/infra@fake_testing_support
Patch Set: Change config ref to have a sandard naming scheme Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 import collections
5 import operator
6
7 from cStringIO import StringIO
8
9
10 class CalledProcessError(Exception):
11 """Almost like subprocess.CalledProcessError, but also captures stderr,
12 and gives prettier error messages.
13 """
14 def __init__(self, returncode, cmd, stdout, stderr):
15 super(CalledProcessError, self).__init__()
16 self.returncode = returncode
17 self.cmd = cmd
18 self.stdout = stdout
19 self.stderr = stderr
20
21 def __str__(self):
22 msg = StringIO()
23
24 suffix = ':' if self.stderr or self.stdout else '.'
25 print >> msg, (
26 "Command %r returned non-zero exit status %d%s"
27 % (self.cmd, self.returncode, suffix)
28 )
29
30 def indent_data(banner, data):
31 print >> msg, banner, '=' * 40
32 msg.writelines(' ' + l for l in data.splitlines(True))
33
34 if self.stdout:
35 indent_data('STDOUT', self.stdout)
36
37 if self.stderr:
38 if self.stdout:
39 print >> msg
40 indent_data('STDERR', self.stderr)
41
42 r = msg.getvalue()
43 if r[-1] != '\n':
44 r += '\n'
45 return r
46
47
48 class cached_property(object):
49 """Like @property, except that the result of get is cached on
50 self.{'_' + fn.__name__}.
51
52 >>> class Test(object):
53 ... @cached_property
54 ... def foo(self):
55 ... print "hello"
56 ... return 10
57 ...
58 >>> t = Test()
59 >>> t.foo
60 hello
61 10
62 >>> t.foo
63 10
64 >>> t.foo = 20
65 >>> t.foo
66 20
67 >>> del t.foo
68 >>> t.foo
69 hello
70 10
71 >>>
72 """
73 def __init__(self, fn):
74 self.func = fn
75 self._iname = "_" + fn.__name__
76 self.__name__ = fn.__name__
77 self.__doc__ = fn.__doc__
78 self.__module__ = fn.__module__
79
80 def __get__(self, inst, cls=None):
81 if inst is None:
82 return self
83 if not hasattr(inst, self._iname):
84 val = self.func(inst)
85 # Some methods call out to another layer to calculate the value. This
86 # higher layer will assign directly to the property, so we have to do
87 # the extra hasattr here to determine if the value has been set as a side
88 # effect of func()
89 if not hasattr(inst, self._iname):
90 setattr(inst, self._iname, val)
91 return getattr(inst, self._iname)
92
93 def __delete__(self, inst):
94 assert inst is not None
95 if hasattr(inst, self._iname):
96 delattr(inst, self._iname)
97
98
99 def freeze(obj):
100 """Takes a jsonish object |obj|, and returns an immutable version of it."""
101 if isinstance(obj, dict):
102 return FrozenDict((freeze(k), freeze(v)) for k, v in obj.iteritems())
103 elif isinstance(obj, list):
104 return tuple(freeze(i) for i in obj)
105 elif isinstance(obj, set):
106 return frozenset(freeze(i) for i in obj)
107 else:
108 hash(obj)
109 return obj
110
111
112 def thaw(obj):
113 """Takes an object from freeze() and returns a mutable copy of it."""
114 if isinstance(obj, FrozenDict):
115 return collections.OrderedDict(
116 (thaw(k), thaw(v)) for k, v in obj.iteritems())
117 elif isinstance(obj, tuple):
118 return list(thaw(i) for i in obj)
119 elif isinstance(obj, frozenset):
120 return set(thaw(i) for i in obj)
121 else:
122 return obj
123
124
125 class FrozenDict(collections.Mapping):
126 """An immutable OrderedDict.
127
128 Modified From: http://stackoverflow.com/a/2704866
129 """
130 def __init__(self, *args, **kwargs):
131 self._d = collections.OrderedDict(*args, **kwargs)
132 self._hash = reduce(operator.xor,
133 (hash(i) for i in enumerate(self._d.iteritems())), 0)
134
135 def __eq__(self, other):
136 if not isinstance(other, collections.Mapping):
137 return NotImplemented
138 if self is other:
139 return True
140 if len(self) != len(other):
141 return False
142 for k, v in self.iteritems():
143 if k not in other or other[k] != v:
144 return False
145 return True
146
147 def __iter__(self):
148 return iter(self._d)
149
150 def __len__(self):
151 return len(self._d)
152
153 def __getitem__(self, key):
154 return self._d[key]
155
156 def __hash__(self):
157 return self._hash
158
159 def __repr__(self):
160 return 'FrozenDict(%r)' % (self._d.items(),)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698