Skip to content

Run Python 3.15 CI with lazy QCoDeS imports + Move and Deprecate modules that overlap classes - #8600

Open
Jens Hedegaard Nielsen (jenshnielsen) wants to merge 6 commits into
microsoft:mainfrom
jenshnielsen:lazy_import_test
Open

Jens Hedegaard Nielsen (jenshnielsen) wants to merge 6 commits into
microsoft:mainfrom
jenshnielsen:lazy_import_test

Conversation

@jenshnielsen

@jenshnielsen Jens Hedegaard Nielsen (jenshnielsen) commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Runs the Python 3.15 CI job with PYTHON_LAZY_IMPORTS=all, limited to imports that involve QCoDeS (see .github/lazy-imports/sitecustomize.py), and fixes what that uncovered.

Why

Some packages export an object with the same name as one of their submodules, e.g. the SR830 class and the qcodes.instrument_drivers.stanford_research.SR830 module, the qcodes.dataset.dond function and the qcodes.dataset.dond subpackage, or qcodes.utils.full_class. Importing a submodule sets it as an attribute on its parent package, so depending on import order stanford_research.SR830 can end up being the module rather than the class. Lazy imports change the import order and expose this.

What changed

Implementation modules moved to private modules

  • qcodes.dataset.dond.* → qcodes.dataset._dond.*
  • qcodes.utils.full_class → qcodes.utils._full_class
  • stanford_research.{SG384,SR560,SR830,SR860,SR865,SR865A,SR86x} → stanford_research._sg384, ._sr560, …
  • basel.{BaselSP983,BaselSP983a,BaselSP983c} → basel._basel_sp983, …

The old module paths remain as deprecated aliases that emit a QCoDeSDeprecationWarning.

Deprecated aliases no longer replace the public object. Importing an alias module would otherwise still overwrite the public object on the package. For example, after from qcodes.instrument_drivers.stanford_research.SR830 import SR830, stanford_research.SR830 would be the module. The affected packages now call _keep_attributes_shadowing_submodules (in qcodes.utils.deprecate), which stops a submodule from replacing an existing attribute of the same name. This can be removed together with the aliases.

Public API decisions

  • The objects exported from the parent packages are unchanged.
  • SR560VoltageParameter (previously VoltageParameter) is now exported. Users construct it themselves, like the Ithaco CurrentParameter.
  • SR830 ChannelBuffer, ChannelTrace and GeneratedSetPoints are renamed to SR830ChannelBuffer, SR830ChannelTrace and SR830GeneratedSetPoints and are private. They are only created by the driver itself.
  • SR86xBufferReadout is private, keeping its name.
  • Old names remain importable from the deprecated module aliases.
  • All other names that were only importable from the moved modules are now considered private. This includes the dond type aliases, DondKWargs, ParameterGroup, ParameterSetEvent and catch_interrupts. The newsfragment asks users to open an issue if they rely on one of them.

do2d_retrace fixed and exported from qcodes.dataset. It previously failed on the first point because the outer sweep parameter was never added to the datasets, and it had no tests. It also called exit_actions after every outer step, and additional_setpoints were not registered. Its only import path was the now-deprecated qcodes.dataset.dond, so it is now exported from qcodes.dataset.

Reviewing

The commits are split to make review easier:

  1. CI: run 3.15 with lazy imports.
  2. The module move, the deprecated aliases and the attribute guard. Moved files contain no changes beyond import paths.
  3. do2d_retrace fix and export.
  4. Export SR560VoltageParameter.
  5. Prefix the SR830 parameter classes.
  6. Newsfragment clarification.

Coverage

Project coverage goes up slightly, from 74.76% to 74.91% in a local run of the full suite (before the last SR560 tests were added). The moved files have the same coverage as before, and the alias modules and the guard are fully covered.

Codecov's patch coverage will look low. Because the old paths still exist as alias modules, GitHub does not detect the moves as renames, so the moved driver code (notably _sr830.py and _sr86x.py) counts as new lines.

Testing

  • Full test suite on Python 3.14.
  • Import, dond and SRS driver tests on Python 3.15.1 with PYTHON_LAZY_IMPORTS=all and the CI sitecustomize. Run locally on Windows without h5py, so the netcdf export tests were not run there.
  • pyright and pre-commit.
  • New tests:
    • Each deprecated alias warns and leaves the public object in place, both normally and under lazy imports.
    • The renamed SR830/SR560 classes are still reachable under their old names.
    • do2d_retrace.
    • The SR560 driver and SR560VoltageParameter.

Newsfragments: 8600.breaking, 8600.breaking.1, 8600.improved.

@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.23077% with 480 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.60%. Comparing base (2605526) to head (06604d7).

Files with missing lines Patch % Lines
...des/instrument_drivers/stanford_research/_sr830.py 19.10% 254 Missing ⚠️
...des/instrument_drivers/stanford_research/_sr86x.py 55.78% 153 Missing ⚠️
...des/instrument_drivers/stanford_research/_sg384.py 12.50% 42 Missing ⚠️
src/qcodes/dataset/_dond/do_2d.py 89.70% 7 Missing ⚠️
...rc/qcodes/instrument_drivers/basel/_basel_sp983.py 73.68% 5 Missing ⚠️
...c/qcodes/instrument_drivers/basel/_basel_sp983c.py 37.50% 5 Missing ⚠️
src/qcodes/dataset/_dond/do_nd.py 99.12% 3 Missing ⚠️
src/qcodes/dataset/_dond/sweeps.py 97.41% 3 Missing ⚠️
...c/qcodes/instrument_drivers/basel/_basel_sp983a.py 93.75% 3 Missing ⚠️
src/qcodes/dataset/_dond/do_nd_utils.py 96.77% 2 Missing ⚠️
... and 3 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8600      +/-   ##
==========================================
+ Coverage   75.37%   75.60%   +0.23%     
==========================================
  Files         308      326      +18     
  Lines       32686    32762      +76     
==========================================
+ Hits        24636    24771     +135     
+ Misses       8050     7991      -59     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Under lazy imports, importing a submodule that has the same name as an
object exported from its package (e.g. stanford_research.SR830) replaces
that object on the package with the module. Move the implementations to
private modules and keep the old module paths as deprecated aliases.

Importing a deprecated alias would still replace the public object on the
package, so the affected packages use a module type that does not let a
submodule replace an existing attribute of the same name.
do2d_retrace did not pass the outer sweep parameter to dond_into, so adding
results failed with missing setpoints. Also register additional_setpoints
in the datasets and call exit_actions once after the measurement.

Export it from qcodes.dataset so it has a public home now that
qcodes.dataset.dond is deprecated.
…vate

VoltageParameter is meant to be constructed by users around a measured
parameter, so give it a driver specific name and export it from the
stanford_research package. The SR830 and SR86x parameter classes are only
created by the drivers themselves, so they stay private.
Rename ChannelBuffer, ChannelTrace and GeneratedSetPoints to
SR830ChannelBuffer, SR830ChannelTrace and SR830GeneratedSetPoints. The old
names remain available from the deprecated SR830 module alias.
@jenshnielsen Jens Hedegaard Nielsen (jenshnielsen) changed the title [wip] Run Python 3.15 CI with lazy QCoDeS imports Run Python 3.15 CI with lazy QCoDeS imports + Move and Deprecate modules that overlap classes Nov 7, 2026
)

LOG = logging.getLogger(__name__)
TRACER = trace.get_tracer(__name__)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this dod2_retrace is something that we want to deprecate instead. The code is not working on main . It was never documented etc.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant