1 """Copyright (c) 2005-2016, University of Oxford. 4 University of Oxford means the Chancellor, Masters and Scholars of the 5 University of Oxford, having an administrative office at Wellington 6 Square, Oxford OX1 2JD, UK. 8 This file is part of Chaste. 10 Redistribution and use in source and binary forms, with or without 11 modification, 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. 21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 Various helpful utility functions/classes used by PyCml. 39 from xml.dom
import Node
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)))
105 def 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)))
121 DFS =
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()
191 def amara_parse(source, uri=None, rules=None, binderobj=None,
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 call_if(tf, callable, args, kwargs)
# Miscellaneous functions # # ...
def prid(obj, show_cls=False)
def __init__(self, start)
def element_path_cmp(e1, e2)
def __init__(self, level=logging.NOTSET)
def LOG(facility, level, args)
def open_output_stream(fname)
def __init__(self, sources)
def set_colour(self, colour)
def __init__(self, tf=False)
def close_output_stream(stream)
def amara_parse(source, uri=None, rules=None, binderobj=None, prefixes=None)
def __init__(self, args, kwargs)
def DEBUG(facility, args)