loki.tools.util
Functions
|
Force item to a tuple, even if None is provided. |
|
Exception hook that automatically attaches a debugger |
|
Sort the given list of items using binary insertion sort. |
|
Search for the insertion position of a value in a given range of items. |
|
Decorator that memoizes (caches) the result of a function |
|
Yield successive n-sized chunks from l. |
|
Contextmanager to temporarily override a set of dictionary values. |
|
Execute a single command within a given directory or environment |
|
Filter elements in a list while preserving order. |
|
Flatten a hierarchy of nested lists into a plain list. |
Test if graphviz is present and works The import will work as long as the graphviz python wrapper is available, but the underlying binaries may be missing. |
|
|
Find groups of consecutive instances of the same type with more than one element. |
|
Checks if an item is truly iterable using duck typing. |
|
Check if all items in iterable |
|
Apply the context manager only when a condition is fulfilled. |
|
Replace a set of consecutive elements in a larger iterable. |
|
Set an exception hook that is called for uncaught exceptions |
|
Utility function to verify if pytest captures stdout/stderr. |
|
A context manager to temporarily redirect stdout or stderr |
|
Strip inline comments from a source string and return the modified string. |
|
Context manager that specifies a timeout for the code section in its body |
|
Add support for |
Classes
Dict that ignores the casing of string keys. |
|
|
Utility class for indirect, |
|
Descriptor object that stores a weakref to the encapsulated object. |
- as_tuple(item, type=None, length=None)
Force item to a tuple, even if None is provided.
- is_iterable(o)
Checks if an item is truly iterable using duck typing.
This was added because
pymbolic.primitives.Expression
provide an__iter__
method that throws an exception to avoid being iterable. However, with that method defined it is identified as acollections.Iterable
and thus this is a much more reliable test thanisinstance(obj, collections.Iterable)
.
- is_subset(a, b, ordered=True, subsequent=False)
Check if all items in iterable
a
are contained in iterableb
.- Parameters:
a (iterable) – The iterable whose elements are searched in
b
.b (iterable) – The iterable of which
a
is tested to be a subset.ordered (bool, optional) – Require elements to appear in the same order in
a
andb
.subsequent (bool, optional) – If set to False, then other elements are allowed to sit in
b
in-between the elements ofa
. Only relevant when usingordered
.
- Returns:
True if all elements of
a
are found inb
, False otherwise.- Return type:
- flatten(l, is_leaf=None)
Flatten a hierarchy of nested lists into a plain list.
- Parameters:
is_leaf (callable) – Optional function that gets called for each iterable element to decide if it is to be considered as a leaf that does not need further flattening.
- chunks(l, n)
Yield successive n-sized chunks from l.
- execute(command, silent=True, **kwargs)
Execute a single command within a given directory or environment
- Parameters:
silent (bool, optional) – Suppress output by redirecting stdout/stderr (default: True)
stdout (file object, optional) – Redirect stdout to this file object (Note:
silent
overwrites this)stderr (file object, optional) – Redirect stdout to this file object (Note:
silent
overwrites this)cwd (str or
pathlib.Path
) – Directory in which to executecommand
(will be stringified)
- class CaseInsensitiveDict
Bases:
OrderedDict
Dict that ignores the casing of string keys.
Basic idea from: https://stackoverflow.com/questions/2082152/case-insensitive-dictionary
- get(key, default=None)
Return the value for key if key is in the dictionary, else default.
- strip_inline_comments(source, comment_char='!', str_delim='"\'')
Strip inline comments from a source string and return the modified string.
Note: this does only work reliably for Fortran strings at the moment (where quotation marks are escaped by double quotes and thus the string status is kept correct automatically).
- binary_insertion_sort(items, lt=<built-in function lt>)
Sort the given list of items using binary insertion sort.
In the best case (already sorted) this has linear running time O(n) and on average and in the worst case (sorted in reverse order) a quadratic running time O(n*n).
A binary search is used to find the insertion position, which reduces the number of required comparison operations. Hence, this sorting function is particularly useful when comparisons are expensive.
- Parameters:
items (list) – the items to be sorted.
lt – the “less than” comparison operator to use. Default is the standard
<
operator (operator.lt
).
- Returns:
the list of items sorted in ascending order.
This implementation was adapted from https://www.geeksforgeeks.org/binary-insertion-sort/.
- cached_func(func)
Decorator that memoizes (caches) the result of a function
- optional(condition, context_manager, *args, **kwargs)
Apply the context manager only when a condition is fulfilled.
Based on https://stackoverflow.com/a/41251962.
- Parameters:
condition (bool) – The condition that needs to be fulfilled to apply the context manager.
context_manager – The context manager to apply.
- class LazyNodeLookup(anchor, query)
Bases:
object
Utility class for indirect,
weakref
-style lookupsReferences to IR nodes are usually not stable as the IR may be rebuilt at any time. This class offers a way to refer to a node in an IR by encoding how it can be found instead.
Note
Example: Reference a declaration node that contains variable “a”
from loki import LazyNodeLookup, FindNodes, Declaration # Assume this has been initialized before # routine = ... # Create the reference query = lambda x: [d for d in FindNodes(VariableDeclaration).visit(x.spec) if 'a' in d.symbols][0] decl_ref = LazyNodeLookup(routine, query) # Use the reference (this carries out the query) decl = decl_ref()
- Parameters:
- property anchor
- yaml_include_constructor(loader, node)
Add support for
!include
tags to YAML loadActivate via
yaml.add_constructor("!include", yaml_include_constructor)
oryaml.add_constructor("!include", yaml_include_constructor, yaml.SafeLoader)
(for use withyaml.safe_load
).Adapted from JUBE2 (https://fz-juelich.de/jsc/jube) and http://code.activestate.com/recipes/577612-yaml-include-support/
This allows to include other YAML files or parts of them inside a YAML file:
# include.yml tag0: foo: bar tag1: baz: bar
# main.yml nested: !include include.yml nested_filtered: !include include.yml:["tag0"]
which is equivalent to the following:
..code-block:: yaml
- nested:
- tag0:
foo: bar
- tag1:
baz: bar
- nested_filtered:
baz: bar
- auto_post_mortem_debugger(type, value, tb)
Exception hook that automatically attaches a debugger
Activate by calling
set_excepthook(hook=auto_post_mortem_debugger)
.Adapted from https://code.activestate.com/recipes/65287/
- set_excepthook(hook=None)
Set an exception hook that is called for uncaught exceptions
This can be called with
auto_post_mortem_debugger()
to automatically attach a debugger (Pdb or, if installed, Pdb++) when exceptions occur.With
hook
set to None, this will restore the default exception hooksys.__excepthook
.
- timeout(time_in_s, message=None)
Context manager that specifies a timeout for the code section in its body
This is implemented by installing a signal handler for
signal.SIGALRM
and scheduling that signal fortime_in_s
in the future. For that reason, this context manager cannot be nested.A value of 0 for
time_in_s
will not install any timeout.The following example illustrates the usage, which will result in a
RuntimeError
being raised.with timeout(5): sleep(10)
- class WeakrefProperty(*, default=None, frozen=False)
Bases:
object
Descriptor object that stores a weakref to the encapsulated object.
- group_by_class(iterable, klass)
Find groups of consecutive instances of the same type with more than one element.
- Parameters:
iterable (iterable) – Input iterable from which to extract groups
klass (type) – Type by which to group elements in the given iterable
- replace_windowed(iterable, group, subs)
Replace a set of consecutive elements in a larger iterable.
- Parameters:
iterable (iterable) – Input iterable in which to replace elements
group (iterable) – Group of elements to replace in
iterable
subs (any) – Replacement for
group
initerable
- dict_override(base, override)
Contextmanager to temporarily override a set of dictionary values.
- stdchannel_redirected(stdchannel, dest_filename)
A context manager to temporarily redirect stdout or stderr
e.g.:
with stdchannel_redirected(sys.stderr, os.devnull): if compiler.has_function('clock_gettime', libraries=['rt']): libraries.append('rt')
Source: https://stackoverflow.com/a/17753573
Note, that this only works when pytest is invoked with ‘–show-capture’ (or ‘-s’). This can be checked using stdchannel_is_captured(capsys). Additionally, capturing of sys.stdout/sys.stderr needs to be disabled explicitly, i.e., use the fixture capsys and wrap the above:
with capsys.disabled(): with stdchannel_redirected(sys.stdout, 'stdout.log'): function()
- stdchannel_is_captured(capsys)
Utility function to verify if pytest captures stdout/stderr.
This hinders redirecting stdout/stderr for f2py/f90wrap functions.
- Parameters:
capsys – The capsys fixture of the test.
- Returns:
True if pytest captures output, otherwise False.
- Return type:
- graphviz_present()
Test if graphviz is present and works The import will work as long as the graphviz python wrapper is available, but the underlying binaries may be missing.