qcodespp.utils.helpers

Attributes

Classes

Functions

Module Contents

qcodespp.utils.helpers.log
class qcodespp.utils.helpers.NumpyJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

Bases: json.JSONEncoder

Return numpy types as standard types.

default(obj)

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return super().default(o)
qcodespp.utils.helpers.tprint(string, dt=1, tag='default')

Print progress of a loop every dt seconds

qcodespp.utils.helpers.is_sequence(obj)

Test if an object is a sequence.

We do not consider strings or unordered collections like sets to be sequences, but we do accept iterators (such as generators)

qcodespp.utils.helpers.is_sequence_of(obj, types=None, depth=None, shape=None)

Test if object is a sequence of entirely certain class(es).

Args:

obj (any): the object to test.

types (Optional[Union[class, Tuple[class]]]): allowed type(s)

if omitted, we just test the depth/shape

depth (Optional[int]): level of nesting, ie if depth=2 we expect

a sequence of sequences. Default 1 unless shape is supplied.

shape (Optional[Tuple[int]]): the shape of the sequence, ie its

length in each dimension. If depth is omitted, but shape included, we set depth = len(shape)

Returns:

bool, True if every item in obj matches types

qcodespp.utils.helpers.is_function(f, arg_count, coroutine=False)

Check and require a function that can accept the specified number of positional arguments, which either is or is not a coroutine type casting “functions” are allowed, but only in the 1-argument form

Args:

f (callable): function to check arg_count (int): number of argument f should accept coroutine (bool): is a coroutine. Default: False

Return:

bool: is function and accepts the specified number of arguments

qcodespp.utils.helpers.full_class(obj)

The full importable path to an object’s class.

qcodespp.utils.helpers.named_repr(obj)

Enhance the standard repr() with the object’s name attribute.

qcodespp.utils.helpers.deep_update(dest, update)

Recursively update one JSON structure with another.

Only dives into nested dicts; lists get replaced completely. If the original value is a dict and the new value is not, or vice versa, we also replace the value completely.

qcodespp.utils.helpers.permissive_range(start, stop, step)

returns range (as a list of values) with floating point step

inputs:

start, stop, step

always starts at start and moves toward stop, regardless of the sign of step

qcodespp.utils.helpers.make_sweep(start, stop, step=None, num=None)

Generate numbers over a specified interval. Requires start and stop and (step or num) The sign of step is not relevant.

Args:

start (Union[int, float]): The starting value of the sequence.

stop (Union[int, float]): The end value of the sequence.

step (Optional[Union[int, float]]): Spacing between values.

num (Optional[int]): Number of values to generate.

Returns:

numpy.linespace: numbers over a specified interval.

Examples:
>>> make_sweep(0, 10, num=5)
[0.0, 2.5, 5.0, 7.5, 10.0]
>>> make_sweep(5, 10, step=1)
[5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
>>> make_sweep(15, 10.5, step=1.5)
>[15.0, 13.5, 12.0, 10.5]
qcodespp.utils.helpers.wait_secs(finish_clock)

calculate the number of seconds until a given clock time The clock time should be the result of time.perf_counter() Does NOT wait for this time.

class qcodespp.utils.helpers.LogCapture(logger=logging.getLogger())

context manager to grab all log messages, optionally from a specific logger

usage:

with LogCapture() as logs:
    code_that_makes_logs(...)
log_str = logs.value
logger
stashed_handlers
__enter__()
__exit__(type, value, tb)
qcodespp.utils.helpers.make_unique(s, existing)

make string s unique, able to be added to a sequence existing of existing names without duplication, by appending _<int> to it if needed

class qcodespp.utils.helpers.DelegateAttributes

Mixin class to create attributes of this object by delegating them to one or more dicts and/or objects

Also fixes __dir__ so the delegated attributes will show up in dir() and autocomplete

Attributes:
delegate_attr_dicts (list): a list of names (strings) of dictionaries

which are (or will be) attributes of self, whose keys should be treated as attributes of self

delegate_attr_objects (list): a list of names (strings) of objects

which are (or will be) attributes of self, whose attributes should be passed through to self

omit_delegate_attrs (list): a list of attribute names (strings)

to not delegate to any other dict or object

any None entry is ignored

attribute resolution order:
  1. real attributes of this object

  2. keys of each dict in delegate_attr_dicts (in order)

  3. attributes of each object in delegate_attr_objects (in order)

delegate_attr_dicts: List[str] = []
delegate_attr_objects: List[str] = []
omit_delegate_attrs: List[str] = []
__getattr__(key)
__dir__()
qcodespp.utils.helpers.strip_attrs(obj, whitelist=())

Irreversibly remove all direct instance attributes of obj, to help with disposal, breaking circular references.

Args:

obj: object to be stripped whitelist (list): list of names that are not stripped from the object

qcodespp.utils.helpers.compare_dictionaries(dict_1, dict_2, dict_1_name='d1', dict_2_name='d2', path='')

Compare two dictionaries recursively to find non matching elements

Args:

dict_1: dictionary 1 dict_2: dictionary 2 dict_1_name: optional name used in the differences string dict_2_name: ‘’

Returns:

dicts_equal: Boolean dict_differences: formatted string containing the differences

qcodespp.utils.helpers.warn_units(class_name, instance)
qcodespp.utils.helpers.foreground_qt_window(window)

Try as hard as possible to bring a qt window to the front. This will use pywin32 if installed and running on windows as this seems to be the only reliable way to foreground a window. The build-in qt functions often doesn’t work. Note that to use this with pyqtgraphs remote process you should use the ref in that module as in the example below.

Args:

window: handle to qt window to foreground

Examples:
>>> Qtplot.qt_helpers.foreground_qt_window(plot.win)
qcodespp.utils.helpers.add_to_spyder_UMR_excludelist(modulename: str)

Spyder tries to reload any user module. This does not work well for qcodes because it overwrites Class variables. QCoDeS uses these to store global attributes such as default station, monitor and list of instruments. This “feature” can be disabled by the gui. Unfortunately this cannot be disabled in a natural way programmatically so in this hack we replace the global __umr__ instance with a new one containing the module we want to exclude. This will do nothing if Spyder is not found. TODO is there a better way to detect if we are in spyder?

qcodespp.utils.helpers.attribute_set_to(object_: Any, attribute_name: str, new_value: Any)

This context manager allows to change a given attribute of a given object to a new value, and the original value is reverted upon exit of the context manager.

Args:
object_

The object which attribute value is to be changed

attribute_name

The name of the attribute that is to be changed

new_value

The new value to which the attribute of the object is to be changed

qcodespp.utils.helpers.partial_with_docstring(func, docstring, **kwargs)

We want to have a partial function which will allow us access the docstring through the python built-in help function. This is particularly important for client-facing driver methods, whose arguments might not be obvious.

Consider the follow example why this is needed:

>>> from functools import partial
>>> def f():
>>> ... pass
>>> g = partial(f)
>>> g.__doc__ = "bla"
>>> help(g) # this will print an unhelpful message
Args:

func (callable) docstring (str)