labbench.paramattr

class labbench.paramattr.HasParamAttrs(**values)

Bases: object

class labbench.paramattr.KeyAdapterBase

Bases: object

Decorates a labbench.Device subclass to configure its implementation of the key argument passed to labbench.paramattr.property or labbench.paramattr.method descriptors.

This can be use to to automate

Example

Send a message string based on key (simplified from labbench.paramattr.visa_keying()):

import labbench as lb
from labbench import paramattr as attr


class custom_keying(attr.message_keying):
    def get(self, device: lb.Device, scpi_key: str, trait_name=None):
        return device.query(key + '?')

    def set(self, device: lb.Device, scpi_key: str, value, trait_name=None):
        return device.write(f'{scpi_key} {value}')


@custom_keying
class CustomDevice(lb.VISADevice):
    pass
copy(update_key_arguments={})
fill_kwargs(method: Method[T], owner_cls: type[HasParamAttrs]) dict[str, MethodKeywordArgument]

return a dictionary of MethodKeywordArguments from broadcast_kwargs missing from method

get(owner: HasParamAttrs, key: str, attr: ParamAttr[T] | None = None, kwargs: dict[str, Any] = {}) T

this must be implemented by a subclass to support of labbench.parameter.method labbench.parameter.property attributes that are implemented through the key keyword.

get_kwarg_names(key: Any) list[str]

returns a list of arguments for the parameter attribute key.

This must be implemented in order to define labbench.paramattr.method attributes using the key keyword.

getter_factory(owner_cls: type[THasParamAttrs], method: Method[T]) callable

return a getter function implemented with method.key

method_signature(owner_cls: type[THasParamAttrs], method: Method[T], scope='all') Signature
set(owner: HasParamAttrs, key: str, value: T, attr: ParamAttr[T] | None = None, kwargs: dict[str, Any] = {})

this must be implemented by a subclass to support of labbench.parameter.method labbench.parameter.property attributes that are implemented through the key keyword.

setter_factory(owner_cls: type[THasParamAttrs], method: Method[T]) callable

return a getter function implemented with method.key

class labbench.paramattr.ParamAttr(*args, **kws)

Bases: Generic[T]

base class for helper descriptors in labbench.Device. These are multi-tools for type checking, casting, decorators, API wrapping, and callbacks.

The basic types of ParamAttr descriptors implemented in labbench are

  • Value, a simple variable stored in the Device object

  • Property, a parameter of an underlying API (often Device.backend) implemented in the style of a property()

  • Method, a parameter of an underlying API (often Device.backend) implemented as a method that can support additional keyword arguments

Each of these are modules that contain more specialized descriptors targeted toward various python types. Method definitions also use KeywordArgument, which are not used as descriptors.

Parameters:
  • key – specify automatic implementation with the Device (backend-specific)

  • help – the ParamAttr docstring

  • label – a label for the quantity, such as units

  • sets – True if the attribute supports writes

  • gets – True if the attribute supports reads

  • cache – if True, interact with the device only once, then return copies (state attribute only)

  • only – value allowlist; others raise ValueError

  • allow_none – permit None values in addition to the specified type

  • log – whether to emit logging/UI notifications when the value changes

  • inherit – if True, use the definition in a parent class as defaults

ROLE = 'base class'
allow_none: bool = False
cache: bool = False
contains(iterable, value)
copy(new_type=None, default, **update_kws) type[Self]
doc(as_argument=False)
doc_params(skip: list[str] = ['help', 'label'], as_argument: bool = False) str
from_pythonic(value)

convert from a python type representation to the format needed to communicate with the device

get_from_owner(owner: HasParamAttrs, kwargs: dict[str, Any] = {})
gets: bool = True
help: str = ''
inherit: bool = False
label: str = ''
log: bool = True
name = None
only: tuple = ()
set_in_owner(owner: HasParamAttrs, value, kwargs: dict[str, Any] = {})
sets: bool = True
to_pythonic(value)

Convert a value from an unknown type to self._type.

update(obj=None, /, **attrs)

returns self or (if obj is None) or other, after updating its keyword parameters with attrs

validate(value, owner=None)

This is the default validator, which requires that attribute value have the same type as self._type. A ValueError is raised for other types.

Parameters:

value – value to check

Returns:

a valid value

labbench.paramattr.adjust(paramattr: ParamAttr | str, default_or_key: Any, /, **kws) callable[[type[T]], type[T]]

decorates a Device subclass to adjust the definition of the specified ParamAttr.

This can be applied to inherited classes that need one of its parents attributes with an adjusted definition. Multiple decorators can be stacked to the same class definition.

Parameters:
  • paramattr – the ParamAttr name or instance to adjust

  • default_or_key – new default or key argument (these can also be passed in **kws)

Raises:
  • ValueError – invalid type of ParamAttr argument, or when d

  • TypeError – _description_

  • ValueError – _description_

Note

Changes to value defaults are not captured in type hints. Therefore, the defaults in their owning classes will not change in IDEs.

Returns:

HasParamAttrs or Device with adjusted attributes value

labbench.paramattr.get_class_attrs(obj: HasParamAttrs | type[HasParamAttrs]) dict[str, ParamAttr]

returns a mapping of labbench paramattrs defined in obj

labbench.paramattr.hold_attr_notifications(owner: HasParamAttrs)
labbench.paramattr.list_method_attrs(obj: HasParamAttrs | type[HasParamAttrs]) list[str]

returns a mapping of names of labbench method paramattrs defined in obj

labbench.paramattr.list_property_attrs(obj: HasParamAttrs | type[HasParamAttrs]) list[str]

returns a list of names of labbench property paramattrs defined in obj

labbench.paramattr.list_value_attrs(obj: HasParamAttrs | type[HasParamAttrs]) list[str]

returns a mapping of names of labbench value paramattrs defined in obj

class labbench.paramattr.message_keying(*, query_fmt=None, write_fmt=None, write_func=None, query_func=None, remap={})

Bases: KeyAdapterBase

Base class for decorators configure wrapper access to a backend API in of a :class:labbench.Device` class through string key arguments.

Decorated classes connect traits that are defined with the key keyword to trigger backend API calls based on the key. The implementation of the set and get methods determines how the key is used to generate API calls.

Example

A custom implementation:

import labbench as lb
from labbench import paramattr as attr


class custom_keying(attr.message_keying):
    def get(self, device: lb.Device, scpi_key: str, trait_name=None):
        if ' ' in scpi_key:
            key = scpi_key.replace(' ', '? ', 1)
        else:
            key = scpi_key + '?'
        return device.query(key)

    def set(self, device: lb.Device, scpi_key: str, value, trait_name=None):
        if ' ' in scpi_key:
            key = f'{scpi_key},{value}'
        else:
            key = f'{scpi_key} {value}'
        return device.write(key.rstrip())


@custom_keying(remap={True: 'ON', False: 'OFF'})
class CustomDevice(lb.VISADevice):
    pass
copy(update_key_arguments={})
fill_kwargs(method: Method[T], owner_cls: type[HasParamAttrs]) dict[str, MethodKeywordArgument]

return a dictionary of MethodKeywordArguments from broadcast_kwargs missing from method

from_message(msg)
get(owner: HasParamAttrs, scpi_key: str, paramattr: ParamAttr[T] | None, kwargs: dict[str, Any] = {}) T

queries a parameter named scpi_key by sending an SCPI message string.

The command message string is formatted as f’{scpi_key}?’. This is automatically called in wrapper objects on accesses to property traits that defined with ‘key=’ (which then also cast to a pythonic type).

Parameters:
  • key (str) – the name of the parameter to set

  • name (str, None) – name of the trait setting the key (or None to indicate no trait) (ignored)

Returns:

response (str)

get_kwarg_names(s: str) list[str]

returns an argument list based on f-string style curly-brace formatting tokens.

Example

`python # input print(key_adapter.get_kwarg_names('CH{channel}:SV:CENTERFrequency')) ['channel'] `

getter_factory(owner_cls: type[THasParamAttrs], method: Method[T]) callable

return a getter function implemented with method.key

method_signature(owner_cls: type[THasParamAttrs], method: Method[T], scope='all') Signature
set(owner: HasParamAttrs, scpi_key: str, value: T, paramattr: ParamAttr[T] | None, kwargs: dict[str, Any] = {})

writes an SCPI message to set a parameter with a name key to value.

The command message string is formatted as f’{scpi_key} {value}’. This This is automatically called on assignment to property traits that are defined with ‘key=’.

Parameters:
  • scpi_key (str) – the name of the parameter to set

  • value (str) – value to assign

  • name (str, None) – name of the trait setting the key (or None to indicate no trait) (ignored)

setter_factory(owner_cls: type[THasParamAttrs], method: Method[T]) callable

return a getter function implemented with method.key

to_message(value, attr_def: ParamAttr)
labbench.paramattr.observe(obj, handler, name, type_=('get', 'set'))

Register a handler function to be called on changes to attributes defined with ParamAttr.

The handler function takes a single message argument. This dictionary message has the keys

  • new: the updated value

  • old: the previous value

  • owner: the object that owns the attribute

  • name: the name of the attribute

  • ‘event’: ‘set’ or ‘get’

Parameters:
  • handler – the handler function to call when the value changes

  • names – notify only changes to these attribute names (None to disable filtering)

labbench.paramattr.unobserve(obj, handler)

Unregister a handler function from notifications in obj.

class labbench.paramattr.visa_keying(*, query_fmt='{key}?', write_fmt='{key} {value}', remap={})

Bases: message_keying

Decorates a labbench.VISADevice (or subclass) to configure its use of the key argument in all labbench.paramattr.property or labbench.paramattr.method descriptors.

Example

Configure MyDevice to format SCPI queries as ‘{key}?’, and SCPI writes as f’{key} {value}’:

import labbench as lb


@lb.visa_keying(query_fmt='{key}?', write_fmt='{key} {value}')
class MyDevice(lb.VISADevice):
    pass
copy(update_key_arguments={})
fill_kwargs(method: Method[T], owner_cls: type[HasParamAttrs]) dict[str, MethodKeywordArgument]

return a dictionary of MethodKeywordArguments from broadcast_kwargs missing from method

from_message(msg)
get(owner: HasParamAttrs, scpi_key: str, paramattr: ParamAttr[T] | None, kwargs: dict[str, Any] = {}) T

queries a parameter named scpi_key by sending an SCPI message string.

The command message string is formatted as f’{scpi_key}?’. This is automatically called in wrapper objects on accesses to property traits that defined with ‘key=’ (which then also cast to a pythonic type).

Parameters:
  • key (str) – the name of the parameter to set

  • name (str, None) – name of the trait setting the key (or None to indicate no trait) (ignored)

Returns:

response (str)

get_kwarg_names(s: str) list[str]

returns an argument list based on f-string style curly-brace formatting tokens.

Example

`python # input print(key_adapter.get_kwarg_names('CH{channel}:SV:CENTERFrequency')) ['channel'] `

getter_factory(owner_cls: type[THasParamAttrs], method: Method[T]) callable

return a getter function implemented with method.key

method_signature(owner_cls: type[THasParamAttrs], method: Method[T], scope='all') Signature
set(owner: HasParamAttrs, scpi_key: str, value: T, paramattr: ParamAttr[T] | None, kwargs: dict[str, Any] = {})

writes an SCPI message to set a parameter with a name key to value.

The command message string is formatted as f’{scpi_key} {value}’. This This is automatically called on assignment to property traits that are defined with ‘key=’.

Parameters:
  • scpi_key (str) – the name of the parameter to set

  • value (str) – value to assign

  • name (str, None) – name of the trait setting the key (or None to indicate no trait) (ignored)

setter_factory(owner_cls: type[THasParamAttrs], method: Method[T]) callable

return a getter function implemented with method.key

to_message(value, attr_def: ParamAttr)