Skip to content

Config¤

A configuration file is useful when you want to perform a measurement.

Config ¤

Config(source: XMLSource)

Load a configuration file.

Parameters:

Name Type Description Default
source XMLSource

A path-like or file-like object containing the configuration data.

required
Source code in src/msl/equipment/config.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def __init__(self, source: XMLSource) -> None:  # noqa: C901
    """Load a configuration file.

    Args:
        source: A [path-like][path-like object] or [file-like][file-like object]
            object containing the configuration data.
    """
    logger.debug("load configuration %s", source)
    self._source: XMLSource = source
    self._root: Element[str] = parse(source).getroot()  # noqa: S314
    self._registers: dict[str, Register] | None = None
    self._config_equipment: ConfigEquipment = ConfigEquipment(self)

    element = self.find("gpib_library")
    if element is not None and element.text:
        os.environ["GPIB_LIBRARY"] = element.text
        logger.debug("update GPIB_LIBRARY=%s", element.text)

    element = self.find("pyvisa_library")
    if element is not None and element.text:
        os.environ["PYVISA_LIBRARY"] = element.text
        logger.debug("update PyVISA_LIBRARY=%s", element.text)

    path_elements = self.findall("path")
    if path_elements:
        paths: list[str] = []
        os_paths: set[str] = set(os.environ["PATH"].split(os.pathsep))
        for element in path_elements:
            path = element.text
            if not path or not os.path.isdir(path):  # noqa: PTH112
                logger.warning("skipped append to PATH: %r", path)
            elif element.attrib.get("recursive", "false").lower() == "true":
                for directory, _, _ in os.walk(path):
                    if directory not in os_paths and directory not in paths:
                        paths.append(directory)
                        logger.debug("append to PATH: %r", path)
            elif path not in os_paths and path not in paths:
                paths.append(path)
                logger.debug("append to PATH: %r", path)

        os.environ["PATH"] += os.pathsep + os.pathsep.join(paths)

    for element in self.findall("connections"):
        connections.add(*_sources(element.text, "connections"))

equipment property ¤

equipment: ConfigEquipment

Returns the <equipment/> elements in the configuration file like a sequence of Equipment items.

Using the returned object you can access Equipment items by index (based on the order that <equipment/> elements are defined in the configuration file), by the eid attribute value or by the name attribute value. You can also iterate over the Equipment items in the sequence.

See here for examples.

path property ¤

path: str

The path to the configuration file.

registers property ¤

registers: dict[str, Register]

Returns all equipment registers that are specified in the configuration file.

The key in the returned dict is the team value of the corresponding Register.

root property ¤

root: Element[str]

The root element (the first node) in the configuration file.

attrib ¤

attrib(path: str) -> dict[str, bool | float | str]

Get the attributes of the first matching element by tag name or path.

If possible, the value is converted to a bool (true or false case-insensitive), an int or a float, otherwise the value remains a str.

Parameters:

Name Type Description Default
path str

Either an element tag name or an XPath.

required

Returns:

Type Description
dict[str, bool | float | str]

The attributes of the matching path element.

Source code in src/msl/equipment/config.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def attrib(self, path: str) -> dict[str, bool | float | str]:
    """Get the attributes of the first matching element by tag name or path.

    If possible, the value is converted to a [bool][] (`true` or `false` case-insensitive),
    an [int][] or a [float][], otherwise the value remains a [str][].

    Args:
        path: Either an element tag name or an XPath.

    Returns:
        The attributes of the matching `path` element.
    """
    element = self.find(path)
    if element is None:
        return {}
    return {k: to_primitive(v) for k, v in element.attrib.items()}

find ¤

find(path: str) -> Element[str] | None

Find the first matching element by tag name or path.

Parameters:

Name Type Description Default
path str

Either an element tag name or an XPath.

required

Returns:

Type Description
Element[str] | None

The element or None if an element was not found at path.

Source code in src/msl/equipment/config.py
129
130
131
132
133
134
135
136
137
138
def find(self, path: str) -> Element[str] | None:
    """Find the first matching element by tag name or path.

    Args:
        path: Either an element tag name or an XPath.

    Returns:
        The element or `None` if an element was not found at `path`.
    """
    return self._root.find(path)

findall ¤

findall(path: str) -> list[Element[str]]

Find all matching sub-elements by tag name or path.

Parameters:

Name Type Description Default
path str

Either an element tag name or an XPath.

required

Returns:

Type Description
list[Element[str]]

All matching elements in document order.

Source code in src/msl/equipment/config.py
140
141
142
143
144
145
146
147
148
149
def findall(self, path: str) -> list[Element[str]]:
    """Find all matching sub-elements by tag name or path.

    Args:
        path: Either an element tag name or an XPath.

    Returns:
        All matching elements in document order.
    """
    return self._root.findall(path)

value ¤

value(
    path: str, default: None = None
) -> bool | float | str | None
value(path: str, default: bool) -> bool
value(path: str, default: int) -> int
value(path: str, default: float) -> float
value(path: str, default: str) -> str
value(
    path: str, default: bool | float | str | None = None
) -> bool | float | str | None

Gets the value (text) associated with the first matching element.

If possible, the value is converted to a bool (true or false case-insensitive), an int or a float, otherwise the value remains a str.

Parameters:

Name Type Description Default
path str

Either an element tag name or an XPath.

required
default bool | float | str | None

The default value if an element cannot be found.

None

Returns:

Type Description
bool | float | str | None

The value of the element or default if an element was not found at path.

Source code in src/msl/equipment/config.py
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
def value(self, path: str, default: bool | float | str | None = None) -> bool | float | str | None:  # noqa: FBT001
    """Gets the value (text) associated with the first matching element.

    If possible, the value is converted to a [bool][] (`true` or `false` case-insensitive),
    an [int][] or a [float][], otherwise the value remains a [str][].

    Args:
        path: Either an element tag name or an XPath.
        default: The default value if an element cannot be found.

    Returns:
        The value of the element or `default` if an element was not found at `path`.
    """
    element = self.find(path)
    if element is None:
        return default
    if element.text is None:
        return None
    return to_primitive(element.text)

ConfigEquipment ¤

ConfigEquipment(cfg: Config)

Access <equipment/> elements in a configuration file like a sequence of Equipment items.

Parameters:

Name Type Description Default
cfg Config

The configuration instance.

required
Source code in src/msl/equipment/config.py
222
223
224
225
226
227
228
229
230
231
232
233
234
def __init__(self, cfg: Config) -> None:
    """Access `<equipment/>` elements in a configuration file like a sequence of [Equipment][] items.

    Args:
        cfg: The configuration instance.
    """
    self._cfg: Config = cfg
    self._elements: list[Element[str]] = cfg.findall("equipment")
    self._equipment: dict[str, Equipment] = {}  # key=eid
    self._index_map: dict[int, str] = {i: e.attrib["eid"] for i, e in enumerate(self._elements)}
    self._name_map: dict[str, str] = {
        e.attrib["name"]: e.attrib["eid"] for e in self._elements if e.attrib.get("name")
    }

eids property ¤

eids: tuple[str, ...]

Returns the value of the eid attribute for each <equipment/> element in a configuration file.

names property ¤

names: tuple[str, ...]

Returns the value of the name attribute for each <equipment/> element in a configuration file.