Skip to content

Add ParameterMixin for extending parameter functionality #6731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

DCEM
Copy link
Contributor

@DCEM DCEM commented Dec 18, 2024

This commit introduces a general-purpose ParameterMixin designed to allow the extension of QCoDeS Parameters. It enables the addition of new features (e.g., on-cache-change callbacks, interdependent updates, and state reset synchronization) across parameter types without requiring per-parameter customization. It does handle docstring updates, enforces naming and allows to declare compatibility.

It replaces #6700.

@thangleiter
Copy link
Contributor

I think this is a great addition. I have written Parameter subclasses with similar patterns multiple times + several in my measurement code.

@DCEM
Copy link
Contributor Author

DCEM commented Apr 25, 2025

@microsoft-github-policy-service agree

@DCEM DCEM force-pushed the add-ParamterMixin branch 2 times, most recently from 73fea4c to 32a7026 Compare June 18, 2025 10:42
DCEM added 2 commits June 18, 2025 12:50
This commit introduces a general-purpose ParameterMixin designed to allow the extension of QCoDeS Parameters.
It enables the addition of new features (e.g., on-cache-change callbacks, interdependent updates,
and state reset synchronization) across parameter types without requiring per-parameter customization.
It does handle docstring updates, enforces naming and allows to declare compatibility.
@DCEM DCEM force-pushed the add-ParamterMixin branch from 32a7026 to b3ab0fb Compare June 18, 2025 10:50
@DCEM
Copy link
Contributor Author

DCEM commented Jun 18, 2025

Hi, after some time away, I’ve rebased and cleaned up this PR. All type checks (mypy, pyright) and tests pass on my end now. I also fixed up the test and requirements files.

There is one possible issue: in the mixin implementation, I’m dynamically patching the parameter cache’s _update_with method to add the desired callback. I used # type: ignore[method-assign] for this line. I believe this is the most straightforward way without touching the cache implementation itself, but please let me know if you’d prefer a different approach or if you see any risks with this pattern.

Let me know if there’s anything unclear or if you’d like changes! Sorry for the long wait - looking forward to your feedback!

Edit: Thinking about it, the parameter group logic currently lives in the reset mixin, but it could easily be refactored into its own mixin class if desired for future extensions or broader use.
I’m happy to refactor or split things out, but I need some feedback to know if the mixin approach is actually wanted before putting more time in.

@DCEM
Copy link
Contributor Author

DCEM commented Jun 30, 2025

Hi @jenshielsen,
I’d really appreciate feedback on whether this ParameterMixin approach is something you’d consider for QCoDeS core.
If it’s not quite the right fit, no worries—just let me know.

Thanks so much for your time!

@jenshnielsen
Copy link
Collaborator

@DCEM Sorry for the lack of reply. How would you feel about adding the mixins to the qcodes.extensions module rather than the parameters module. This will give us a bit of time to prove out the idea and test it before committing to the Mixins.

@jenshnielsen jenshnielsen requested a review from Copilot July 22, 2025 13:26
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a general-purpose ParameterMixin system for extending QCoDeS Parameters with additional functionality. The implementation provides a framework for adding features like on-cache-change callbacks, interdependent parameter updates, and state reset synchronization across parameter types without requiring per-parameter customization.

Key changes include:

  • Base ParameterMixin class with compatibility checking and naming enforcement
  • Three concrete mixins: OnCacheChangeParameterMixin, InterdependentParameterMixin, and SetCacheValueOnResetParameterMixin
  • Comprehensive test suite covering all mixin functionality

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/qcodes/parameters/parameter_mixin.py Core implementation of the ParameterMixin framework and three concrete mixins
src/qcodes/parameters/init.py Exports the new mixin classes in the public API
tests/parameter/test_parameter_mixin.py Tests for base ParameterMixin functionality including compatibility and naming
tests/parameter/test_parameter_mixin_on_cache_change.py Tests for OnCacheChangeParameterMixin functionality
tests/parameter/test_parameter_mixin_interdependent.py Tests for InterdependentParameterMixin functionality
tests/parameter/test_parameter_mixin_set_cache_value_on_reset.py Tests for SetCacheValueOnResetParameterMixin functionality
Comments suppressed due to low confidence (8)

tests/parameter/test_parameter_mixin_on_cache_change.py:200

  • The parameter is added with name 'test_param' but accessed as 'test_parameter'. This should be 'mock_instr.test_parameter.get()' for consistency.
    assert mock_instr.test_param.get() is None

tests/parameter/test_parameter_mixin_on_cache_change.py:202

  • The parameter is accessed as 'test_param' but was added with name 'test_param'. However, line 189 assigns it to 'test_parameter'. This should be 'mock_instr.test_parameter.set(5)' for consistency.
    mock_instr.test_param.set(5)

tests/parameter/test_parameter_mixin_on_cache_change.py:205

  • Inconsistent parameter name usage. Should be 'mock_instr.test_parameter.get()' to match the assignment on line 187.
    assert mock_instr.test_param.get() == 5

tests/parameter/test_parameter_mixin_on_cache_change.py:209

  • Inconsistent parameter name usage. Should be 'mock_instr.test_parameter.set(7)' to match the assignment on line 187.
    mock_instr.test_param.set(7)

tests/parameter/test_parameter_mixin_on_cache_change.py:212

  • Inconsistent parameter name usage. Should be 'mock_instr.test_parameter.get()' to match the assignment on line 187.
    assert mock_instr.test_param.get() == 7

tests/parameter/test_parameter_mixin_on_cache_change.py:216

  • Inconsistent parameter name usage. Should be 'mock_instr.test_parameter.set(7)' to match the assignment on line 187.
    mock_instr.test_param.set(7)

tests/parameter/test_parameter_mixin_on_cache_change.py:219

  • Inconsistent parameter name usage. Should be 'mock_instr.test_parameter.cache._update_with(value=110, raw_value=100)' to match the assignment on line 187.
    mock_instr.test_param.cache._update_with(value=110, raw_value=100)

@DCEM
Copy link
Contributor Author

DCEM commented Jul 23, 2025

After writing the ParameterMixin, I thought it could help reduce code redundancy and save people from having to reinvent the same solutions. I think it could be a worthwhile addition to QCoDeS, and I’m happy to put it wherever you prefer—or not add it, if you don’t think it’s a fit.

Just let me know how you’d like to proceed!

@jenshnielsen
Copy link
Collaborator

@DCEM I think something like the ParameterMixin is a good idea. I don't have the time to more detailed think about the design and how it would fit in which makes me think that if we add it as an extension then we have some time to actually use it and test it in real world use cases before committing to extending the parameter modules api.

@DCEM
Copy link
Contributor Author

DCEM commented Jul 24, 2025

Hi @jenshnielsen,

Moving the mixin to extensions makes sense to me. Having it where it’s easy to use, test, and modify seems like a good choice, and it really is a modular parameter "extension". I’m happy to move the code there.

Two questions on my end:

  • For placement: should the mixin go as a single file in qcodes/extensions, or would you prefer a subdirectory like
    qcodes/extensions/parameter/ or qcodes/extensions/parametermixin/? Or is there a different location you’d recommend?

  • On implementation: to avoid touching the parameter cache code directly, I decided to wrap the parameter cache’s _update_with method dynamically (using # type: ignore[method-assign]). Do you see any risks with this approach, or would you prefer a different method?

Thanks again for your feedback!

@jenshnielsen
Copy link
Collaborator

@DCEM

  • I don't have a strong preference but let's put is in a parameters subfolder. One file in that folder is fine thou if you prefer.
  • If possible I prefer to avoid type ignores but I totally understand if you don't want to touch the cache too much. I think the current wrapper should be fine. It may be possible to get pyright (but perhaps not mypy) to type check with something like this. I will have a look at some point

Copy link

codecov bot commented Jul 25, 2025

Codecov Report

Attention: Patch coverage is 66.23932% with 79 lines in your changes missing coverage. Please review.

Project coverage is 59.34%. Comparing base (1365c3a) to head (6ae5154).
Report is 305 commits behind head on main.

Files with missing lines Patch % Lines
src/qcodes/parameters/parameter_mixin.py 66.23% 79 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6731      +/-   ##
==========================================
- Coverage   59.94%   59.34%   -0.60%     
==========================================
  Files         342      341       -1     
  Lines       31517    30971     -546     
==========================================
- Hits        18893    18381     -512     
+ Misses      12624    12590      -34     

☔ View full report in Codecov by Sentry.
📢 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.

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.

3 participants