QCoDeS [UNRELEASED DRAFT] (2026-09-25)

Improved:

  • The documentation on naming instrument drivers (in the Contributor guide and in the “Creating Instrument Drivers” example notebook) has been updated to state that instrument driver modules should be named using lower case snake_case, e.g. weinschel_8320.py. Vendor and model capitalization belongs in the class name (Weinschel8320) and not in the module name. (#8356)

  • Exceptions raised by QCoDeS drivers are now more specific.

    The ruff rule TRY002 (raise-vanilla-class) has been enabled. A number of drivers raised a bare Exception; these now raise a specific builtin exception instead. Invalid arguments raise ValueError, using the instrument in an unsupported state raises RuntimeError and selecting an unimplemented acquisition mode on the AlazarTech ATS raises NotImplementedError. Code that catches Exception is unaffected since all of these are subclasses of Exception.

    In addition, two catch-all exception handlers have been narrowed to the specific exceptions that the guarded code can actually raise: reading a screenshot from the Keysight Infiniium now only handles OSError and VisaIOError, and waiting for the Tektronix AWG5014 to become ready only handles VisaIOError. Both previously swallowed unrelated errors.

    Finally, the coding style section of the contributor documentation now points at ruff check and ruff format, configured in pyproject.toml, rather than the long removed pycodestyle and flake8 based workflow. (#8368)

Improved Drivers:

  • The Infiniium driver now tests explicitly for the type of parent instrument when required and used cast where pyvisa types the return of read_binary_values/query_binary_values as a Sequence[float] regardless of the requested container. This replaces five type checker suppressions. (#8457)

New:

  • The method for setting a parameter’s cache from a raw value as reported by the instrument is now public as Parameter.cache.set_from_raw_value. It is the raw-side counterpart of Parameter.cache.set and applies the same conversions as a get (get_parser, scale, offset and val_mapping). This is useful for drivers that populate the caches of many parameters from a single bulk instrument reply without issuing a get per parameter. The previous private _set_from_raw_value is kept as a backwards-compatible alias. (#8484)

Under the hood:

  • Enable the ruff rule N999 (invalid-module-name). Instrument driver modules that are part of the public qcodes namespace are exempted via lint.pep8-naming.extend-ignore-names in pyproject.toml so that no public module names change. Test modules with invalid names have been renamed to lower case. (#8356)

  • CombinedParameter.parameter is now a small dataclass holding the name, full_name, label and unit of the combined parameter, replacing a lambda that had those attributes attached to it. It remains callable, and calling it returns None as before. (#8364)

  • Two additional ruff lint rules have been enabled.

    TRY004 (type-check-without-type-error) ensures that new code raises TypeError when rejecting a value because of its type. Existing type checks that raise ValueError or RuntimeError are unchanged and carry an explicit noqa comment, since TypeError is not a subclass of either and changing them would break user code that catches the current exception.

    S110 (try-except-pass) flags exception handlers that silently pass. No behaviour changed as a result: the only remaining silent handlers are in teardown paths that must never raise or log, and they are now explicitly marked as intentional. (#8368)

  • Enable the ruff rule BLE001 (blind-except). Places where QCoDeS intentionally catches a broad exception are now explicitly marked, and several catch-all handlers now log the full traceback using Logger.exception rather than only the exception message. The private module level loggers named _LOG have been renamed to _LOGGER. (#8498)