Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@ repos:
# Ruff version.
rev: v0.15.11
hooks:
- id: ruff-check
types_or: [python, pyi, jupyter, toml]
args: [ --fix, --exit-non-zero-on-fix ]
- id: ruff-format
- id: ruff-check
types_or: [python, pyi, jupyter, toml]
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-ast
- id: check-json
exclude: asv.conf.json
- id: check-toml
- id: check-yaml
- id: check-case-conflict
- id: debug-statements
- id: mixed-line-ending
args: ['--fix=no']
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-ast
- id: check-json
exclude: asv.conf.json
- id: check-toml
- id: check-yaml
- id: check-case-conflict
- id: debug-statements
- id: mixed-line-ending
args: ["--fix=no"]
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
hooks:
- id: gitleaks
- repo: https://github.com/jumanjihouse/pre-commit-hooks
rev: 3.0.0
- id: gitleaks
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
hooks:
- id: shellcheck
- id: shellcheck
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,12 @@ reportUnnecessaryContains = "none"

[tool.pytest.ini_options]
minversion = "7.2"
testpaths = "tests"
testpaths = ["tests","src"] # we include src to collect doctests
addopts = "-n auto --dist=loadfile --cov-config=pyproject.toml"
asyncio_default_fixture_loop_scope = "function"
markers = "serial"


# we ignore warnings
# triggered by third party packages
# and error on all other warnings
Expand Down
7 changes: 5 additions & 2 deletions src/qcodes/configuration/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def add(
default: default value, stored only in the schema

Examples:
>>> defaults.add("trace_color", "blue", "string", "description")
>>> defaults.add("trace_color", "blue", "string", "description") # doctest: +SKIP

will update the config:

Expand Down Expand Up @@ -477,7 +477,10 @@ def __getattr__(self, name: str) -> Any:
"""
Overwrite ``__getattr__`` to provide dot access
"""
return self.__getitem__(name)
try:
return self.__getitem__(name)
except KeyError:
raise AttributeError(name)

def __setattr__(self, key: str, value: Any) -> None:
"""
Expand Down
10 changes: 4 additions & 6 deletions src/qcodes/dataset/guid_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,10 @@ def guids_from_list_str(s: str) -> tuple[str, ...] | None:
For an empty list/tuple/set or empty string an empty tuple is returned.

Examples:
>>> guids_from_str(
"['07fd7195-c51e-44d6-a085-fa8274cf00d6', \
'070d7195-c51e-44d6-a085-fa8274cf00d6']")
will return
('07fd7195-c51e-44d6-a085-fa8274cf00d6',
'070d7195-c51e-44d6-a085-fa8274cf00d6')
>>> guids_from_list_str(
... "['07fd7195-c51e-44d6-a085-fa8274cf00d6','070d7195-c51e-44d6-a085-fa8274cf00d6']"
... )
('07fd7195-c51e-44d6-a085-fa8274cf00d6', '070d7195-c51e-44d6-a085-fa8274cf00d6')

"""
if s == "":
Expand Down
2 changes: 1 addition & 1 deletion src/qcodes/dataset/measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def add_result(self, *result_tuples: ResType) -> None:
is four dimensional (v1, v2, c1, c2). The corresponding call
to this function would be

>>> datasaver.add_result((v1, 0.1), (v2, 0.2), (c1, 5), (c2, -2.1))
>>> datasaver.add_result((v1, 0.1), (v2, 0.2), (c1, 5), (c2, -2.1)) # doctest: +SKIP

For better performance, this function does not immediately write to
the database, but keeps the results in memory. Writing happens every
Expand Down
2 changes: 1 addition & 1 deletion src/qcodes/instrument/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def close_all(cls) -> None:
closed.

Examples:
>>> atexit.register(qc.Instrument.close_all())
>>> atexit.register(qc.Instrument.close_all()) # doctest: +SKIP

"""
log.info("Closing all registered instruments")
Expand Down
86 changes: 50 additions & 36 deletions src/qcodes/instrument_drivers/Keithley/_Keithley_2600.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,41 +922,49 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None:

**Direct usage (returns ndarray)**

Example 1D::
Example 1D:

.. code-block:: python

>>> from qcodes.dataset import LinSweep
>>> keith.smua.setup_fastsweep(LinSweep(keith.smua.volt, 0, 1, 100))
>>> data = keith.smua.fastsweep() # or: keith.smua.fastsweep.get()
>>> data.shape
from qcodes.dataset import LinSweep
keith.smua.setup_fastsweep(LinSweep(keith.smua.volt, 0, 1, 100))
data = keith.smua.fastsweep() # or: keith.smua.fastsweep.get()
data.shape
(100,)

Example 2D (inner=smub, outer=smua)::
Example 2D (inner=smub, outer=smua):

.. code-block:: python

>>> from qcodes.dataset import LinSweep
>>> keith.smua.setup_fastsweep(
... LinSweep(keith.smub.volt, 0, 1, 100), # inner
... LinSweep(keith.smua.volt, 0, 0.5, 20), # outer
... )
>>> data = keith.smub.fastsweep() # call on inner channel
>>> data.shape
from qcodes.dataset import LinSweep
keith.smua.setup_fastsweep(
LinSweep(keith.smub.volt, 0, 1, 100), # inner
LinSweep(keith.smua.volt, 0, 0.5, 20), # outer
)
data = keith.smub.fastsweep() # call on inner channel
data.shape
(20, 100)

**Dataset logging with do0d**

To log the fast sweep into a QCoDeS dataset, use :func:`do0d`
with the ``fastsweep`` parameter::
with the ``fastsweep`` parameter:

.. code-block:: python

from qcodes.dataset import LinSweep, do0d
keith.smua.setup_fastsweep(LinSweep(keith.smua.volt, 0, 1, 100))
ds, _, _ = do0d(keith.smua.fastsweep)

>>> from qcodes.dataset import LinSweep, do0d
>>> keith.smua.setup_fastsweep(LinSweep(keith.smua.volt, 0, 1, 100))
>>> ds, _, _ = do0d(keith.smua.fastsweep)
For a 2D sweep (inner=smub, outer=smua):

For a 2D sweep (inner=smub, outer=smua)::
.. code-block:: python

>>> from qcodes.dataset import LinSweep, do0d
>>> keith.smua.setup_fastsweep(
... LinSweep(keith.smub.volt, 0, 1, 100), # inner
... LinSweep(keith.smua.volt, 0, 0.5, 20), # outer
... )
from qcodes.dataset import LinSweep, do0d
keith.smua.setup_fastsweep(
LinSweep(keith.smub.volt, 0, 1, 100), # inner
LinSweep(keith.smua.volt, 0, 0.5, 20), # outer
)
"""

self.timetrace_npts: Parameter = self.add_parameter(
Expand Down Expand Up @@ -1065,25 +1073,31 @@ def setup_fastsweep(

Example 1D:

>>> from qcodes.dataset import LinSweep
>>> keith.smua.setup_fastsweep(LinSweep(keith.smua.volt, 0, 1, 100))
>>> ds, _, _ = do0d(keith.smua.fastsweep)
.. code-block:: python

from qcodes.dataset import LinSweep
keith.smua.setup_fastsweep(LinSweep(keith.smua.volt, 0, 1, 100))
ds, _, _ = do0d(keith.smua.fastsweep)

Example 2D (inner=smua, outer=smub):

>>> keith.smua.setup_fastsweep(
... LinSweep(keith.smua.volt, 0, 1, 100), # inner
... LinSweep(keith.smub.volt, 0, 0.5, 20), # outer
... )
>>> ds, _, _ = do0d(keith.smua.fastsweep) # call on inner channel
.. code-block:: python

keith.smua.setup_fastsweep(
LinSweep(keith.smua.volt, 0, 1, 100), # inner
LinSweep(keith.smub.volt, 0, 0.5, 20), # outer
)
ds, _, _ = do0d(keith.smua.fastsweep) # call on inner channel

Example 2D (inner=smub, outer=smua):

>>> keith.smua.setup_fastsweep(
... LinSweep(keith.smub.volt, 0, 1, 100), # inner
... LinSweep(keith.smua.volt, 0, 0.5, 20), # outer
... )
>>> ds, _, _ = do0d(keith.smub.fastsweep) # call on inner channel
.. code-block:: python

keith.smua.setup_fastsweep(
LinSweep(keith.smub.volt, 0, 1, 100), # inner
LinSweep(keith.smua.volt, 0, 0.5, 20), # outer
)
ds, _, _ = do0d(keith.smub.fastsweep) # call on inner channel

"""

Expand Down
8 changes: 5 additions & 3 deletions src/qcodes/instrument_drivers/Keysight/keysight_e4980a.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ class KeysightE4980AMeasurementPair(MultiParameter):
To create a measurement data with capacitance=1.2, and
dissipation_factor=3.4.

>>> data = KeysightE4980AMeasurementPair(name="CPD",
names=("capacitance", "dissipation_factor"),
units=("F", ""))
>>> data = KeysightE4980AMeasurementPair(
... name="CPD",
... names=("capacitance", "dissipation_factor"),
... units=("F", ""),
... )
>>> data.set((1.2, 3.4))
>>> data.get()
(1.2, 3.4)
Expand Down
4 changes: 2 additions & 2 deletions src/qcodes/instrument_drivers/Lakeshore/lakeshore_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,8 @@ def _get_sum_terms(available_terms: "Sequence[int]", number: int) -> list[int]:

Example:
>>> terms = [1, 16, 32, 64, 128]
>>> get_sum_terms(terms, 96)
... [64, 32] # This is correct because 96=64+32
>>> [int(x) for x in LakeshoreBaseSensorChannel._get_sum_terms(terms, 96)]
[64, 32]
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.

Readd comment


"""
terms_in_number: list[int] = []
Expand Down
31 changes: 31 additions & 0 deletions src/qcodes/instrument_drivers/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os
from pathlib import Path

# Drivers that require optional third-party libraries not generally available.
# These must be excluded from doctest collection to avoid ImportErrors.
collect_ignore_glob = [
os.path.join("Galil", "*"),
os.path.join("Minicircuits", "*"),
os.path.join("QuantumDesign", "DynaCoolPPMS", "private", "*"),
]


def _find_deprecated_driver_modules() -> list[str]:
"""
Scan for deprecated driver alias modules that emit deprecation warnings
on import. Importing these during doctest collection triggers noisy
warnings and serves no purpose since they contain no doctests.
"""
drivers_dir = Path(__file__).parent
deprecated: list[str] = []
for path in sorted(drivers_dir.rglob("*.py")):
try:
text = path.read_text(encoding="utf-8")
except Exception:
continue
if "module is deprecated" in text:
deprecated.append(str(path.relative_to(drivers_dir)))
return deprecated


collect_ignore = _find_deprecated_driver_modules()
14 changes: 11 additions & 3 deletions src/qcodes/instrument_drivers/rigol/Rigol_DG1062.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,19 @@ def apply(self, **kwargs: Any) -> None:
"""
Public interface to apply a waveform on the channel
Example:
>>> gd = RigolDG1062("gd", "TCPIP0::169.254.187.99::inst0::INSTR")
>>> gd.channels[0].apply(waveform="SIN", freq=1E3, ampl=1.0, offset=0, phase=0)

.. code-block:: python

gd = RigolDG1062("gd", "TCPIP0::169.254.187.99::inst0::INSTR")
gd.channels[0].apply(waveform="SIN", freq=1E3, ampl=1.0, offset=0, phase=0)

Valid waveforms are: HARM, NOIS, RAMP, SIN, SQU, TRI, USER, DC, ARB
To find the correct arguments of each waveform we can e.g. do:
>>> help(gd.channels[0].sin)

.. code-block:: python

help(gd.channels[0].sin)

Notice the lower case when accessing the waveform through convenience
functions.
If not kwargs are given a dictionary with the current waveform
Expand Down
6 changes: 4 additions & 2 deletions src/qcodes/instrument_drivers/stahl/stahl.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ def chain(*functions: Callable[..., Any]) -> Callable[..., Any]:

Example:
>>> def f():
>>> return "1.2"
>>> chain(f, float)() # return 1.2 as float
... return "1.2"
>>> chain(f, float)()
1.2


"""

Expand Down
11 changes: 8 additions & 3 deletions src/qcodes/instrument_drivers/stanford_research/SR830.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,10 +769,15 @@ def snap(self, *parameters: str) -> tuple[float, ...]:
A tuple of floating point values in the same order as requested.

Examples:
>>> lockin.snap('x','y') -> tuple(x,y)

>>> lockin.snap('aux1','aux2','freq','phase')
>>> -> tuple(aux1,aux2,freq,phase)
.. code-block:: python

lockin.snap('x','y') -> tuple(x,y)

.. code-block:: python

lockin.snap('aux1','aux2','freq','phase')
-> tuple(aux1,aux2,freq,phase)

Note:
Volts for x, y, r, and aux 1-4
Expand Down
18 changes: 11 additions & 7 deletions src/qcodes/logger/instrument_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ class InstrumentLoggerAdapter(logging.LoggerAdapter):
instance.

The context data gets stored in the `extra` dictionary as a property of the
Adapter. It is filled by the ``__init__`` method::
Adapter. It is filled by the ``__init__`` method:

>>> LoggerAdapter(log, {'instrument': instrument_instance})
.. code-block:: python

LoggerAdapter(log, {'instrument': instrument_instance})

"""

Expand Down Expand Up @@ -163,11 +165,13 @@ def filter_instrument(
the supplied instruments to pass.

Example:
>>> h1, h2 = logger.get_console_handler(), logger.get_file_handler()
>>> with logger.filter_instruments((qdac, dmm2), handler=[h1, h2]):
>>> qdac.ch01(1) # logged
>>> v1 = dmm2.v() # logged
>>> v2 = keithley.v() # not logged
.. code-block:: python

h1, h2 = logger.get_console_handler(), logger.get_file_handler()
with logger.filter_instruments((qdac, dmm2), handler=[h1, h2]):
qdac.ch01(1) # logged
v1 = dmm2.v() # logged
v2 = keithley.v() # not logged

Args:
instrument: The instrument or sequence of instruments to enable
Expand Down
9 changes: 6 additions & 3 deletions src/qcodes/logger/log_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,12 @@ def capture_dataframe(
Context manager to capture the logs in a :class:`pd.DataFrame`

Example:
>>> with logger.capture_dataframe() as (handler, cb):
>>> qdac.ch01(1) # some commands
>>> data_frame = cb()

.. code-block:: python

with logger.capture_dataframe() as (handler, cb):
qdac.ch01(1) # some commands
data_frame = cb()

Args:
level: Level at which to capture.
Expand Down
Loading
Loading