1"""Copyright (c) 2005-2016, University of Oxford.
4University of Oxford means the Chancellor, Masters and Scholars of the
5University of Oxford, having an administrative office at Wellington
6Square, Oxford OX1 2JD, UK.
8This file is part of Chaste.
10Redistribution and use in source and binary forms, with or without
11modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice,
13 this list of conditions and the following disclaimer.
14 * Redistributions
in binary form must reproduce the above copyright notice,
15 this list of conditions
and the following disclaimer
in the documentation
16 and/
or other materials provided
with the distribution.
17 * Neither the name of the University of Oxford nor the names of its
18 contributors may be used to endorse
or promote products derived
from this
19 software without specific prior written permission.
21THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS"
22AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34Various helpful utility functions/classes used by PyCml.
39from xml.dom import Node # For nodeType values
45__all__ = ['OnlyWarningsFilter', 'OnlyDebugFilter', 'OnlyTheseSourcesFilter', 'NotifyHandler',
47 'Colourable',
'DFS',
'Sentinel',
'unitary_iterator',
48 'amara_parse',
'element_path',
'element_path_cmp',
'element_xpath',
'brief_xml',
49 'call_if',
'max_i',
'prid',
'add_dicts',
50 'open_output_stream',
'close_output_stream']
59 """A filter that only passes warning messages."""
61 return (logging.WARNING <= rec.levelno < logging.ERROR)
65 """A filter that only passes debug messages."""
67 return (logging.DEBUG <= rec.levelno < logging.INFO)
71 """A filter that only emits messages from the given sources."""
73 logging.Filter.__init__(self)
81 A logging handler that just notes if any messages are logged.
84 logging.Handler.__init__(self, level=level)
91 """Reset the handler, as if no messages have occurred."""
96 """Log a debug message to facility.
98 Arguments are treated as for the
print statement.
100 logger = logging.getLogger(facility)
101 if logger.isEnabledFor(logging.DEBUG):
102 logger.debug(
' '.join(map(str, args)))
105def LOG(facility, level, *args):
106 """Log a message to facility with the given level.
108 Arguments are treated as for the
print statement.
110 logger = logging.getLogger(facility)
111 if logger.isEnabledFor(level):
112 logger.log(level,
' '.join(map(str, args)))
121DFS =
Enum(
'White',
'Gray',
'Black')
125 A mixin class for objects that have a colour attribute, and so support
126 a depth-first search.
129 super(Colourable, self).
__init__(*args, **kwargs)
143 """A simple true/false store that can be used as a default parameter value in recursive calls.
145 This provides a slightly nicer looking alternative to code such as:
150 if xyz: done[0] =
True
153 The list can be replaced
with a Sentinel instance.
156 """Create a new, unset sentinel."""
160 """Test whether the sentinel has been set."""
164 """Set the sentinel."""
169 """An iterator over a single item."""
179 raise StopIteration()
193 """Convenience function for parsing XML.
195 Works just as amara.parse,
except that
if source
is '-' then
196 it reads
from standard input.
199 return amara.parse(sys.stdin, uri=uri, rules=rules,
200 binderobj=binderobj, prefixes=prefixes)
202 return amara.parse(source, uri=uri, rules=rules,
203 binderobj=binderobj, prefixes=prefixes)
207 """Find the path from the root element to this element."""
208 if hasattr(elt,
'xml_parent'):
210 for child
in elt.xml_parent.xml_children:
211 if getattr(child,
'nodeType',
None) == Node.ELEMENT_NODE:
221 """Compare 2 elements by comparing their paths from the root element."""
226 """Return an xpath expression that will select this element."""
228 xpath =
u'/*[' +
u']/*['.join(map(str, indices)) +
u']'
233 """Print a more concise version of elt.xml() that omits all attributes."""
235 if getattr(elt,
'nodeType',
None) == Node.ELEMENT_NODE:
236 children = getattr(elt,
'xml_children', [])
238 s +=
'<' + elt.localName +
'>'
239 for child
in children:
241 s +=
'</' + elt.localName +
'>'
243 s +=
'<' + elt.localName +
'/>'
256 """Call the given callable with the given arguments iff tf is True."""
258 return callable(*args, **kwargs)
262 """Find the maximum entry of an iterable, and return it with its index.
264 Returns (i, m) where i is the index of m, the maximum entry of `it`.
267 for i, val
in enumerate(it):
268 if m
is None or val > m:
274 """Get the id of an object as a hex string, optionally with its class/type."""
285 """Add multiple dictionaries together.
287 Updates the first input dictionary by adding values from
288 subsequent inputs. Produces a dictionary
with keys taken
from the
289 input dictionaries,
and values being the sum of the corresponding
290 values
in all inputs.
291 Assumes values are numeric.
294 for k, v
in d.iteritems():
295 r[k] = r.get(k, 0) + v
299 """Open fname for output.
301 fname should be a local filename, or '-' for standard output.
302 Additionally, the names
'stdout' and 'stderr' have the usual
305 if fname ==
'-' or fname ==
'stdout':
307 elif fname ==
'stderr':
310 stream = open(fname,
'w')
316 Close the given output stream, unless it's one of the standard streams
317 (i.e. sys.stdout or sys.stderr).
318 Note that closing a stream multiple times
is safe.
320 if not stream
is sys.stdout
and not stream
is sys.stderr:
def set_colour(self, colour)
def __init__(self, *args, **kwargs)
def __init__(self, level=logging.NOTSET)
def __init__(self, sources)
def __init__(self, tf=False)
def __init__(self, start)
def open_output_stream(fname)
def amara_parse(source, uri=None, rules=None, binderobj=None, prefixes=None)
def LOG(facility, level, *args)
def prid(obj, show_cls=False)
def call_if(tf, callable, *args, **kwargs)
def close_output_stream(stream)
def DEBUG(facility, *args)
def element_path_cmp(e1, e2)