Skip to content

Commit

Permalink
Merge pull request #5721 from jenshnielsen/pyright_standard
Browse files Browse the repository at this point in the history
Run pyright with standard checks
  • Loading branch information
jenshnielsen authored Mar 4, 2024
2 parents 0de1008 + b2a94b6 commit 2943def
Show file tree
Hide file tree
Showing 25 changed files with 209 additions and 110 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
if: ${{ !matrix.min-version }}
- uses: jakebailey/pyright-action@b8ffdb7aa4a15fab942303261611eaa541f3f8b0 # v2.2.1
with:
version: 1.1.349
version: 1.1.351
if: ${{ !matrix.min-version }}
- name: Run Mypy
run: mypy -p qcodes
Expand Down
9 changes: 9 additions & 0 deletions docs/changes/newsfragments/5721.breaking
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
QCoDeS is now type checked to ensure that subclasses are implemented in a way consistent with the parent class.
This has resulted in a number of changes to the API. The following is a list of the changes that have been made
to the API to make subclasses match their parent class. These changes are not expected to break any existing code, since they are
primarily in positional arguments or unused arguments.

* The first argument to `NumpyJSONEncoder.default` has changed from `obj` to `o` to match the naming in the std library `json.JSONEncoder.default`.
* Unused args `idn_part` and `being_time` to `QDevQDac.connect_message` have been changed to `idn_param` and `begin_time` respectively to match the parent class.
* Unused arguments to stub methods `DSOTraceParam.setpoints`, `DSOTraceParam.unit` and `FormattedSweep.setpoints` have been changed to match the parent class.
* Alazar `DemodulationAcquisitionController.handle_buffer` the first argument has been renamed from `data` to `buffer` to match the parent class.
7 changes: 1 addition & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,8 @@ ignore = [
reportMissingTypeStubs = true
reportDeprecated = true
stubPath = "typings/stubs"
# we would like to move this to at least standard
# eventually. From 1.1.339 onwards standard is the default
# for now we enable all of standard except for
# incompatibleMethodOverride which we have a lot of
typeCheckingMode = "standard"
reportIncompatibleMethodOverride = false

typeCheckingMode = "standard"

[tool.pytest.ini_options]
minversion = "7.2"
Expand Down
12 changes: 9 additions & 3 deletions src/qcodes/dataset/legacy_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ def store_array_to_database(datasaver: DataSaver, array: DataArray) -> int:
datasaver.add_result((array.set_arrays[0].array_id, i),
(array.array_id, array[index]))
else:
raise NotImplementedError('The exporter only currently handles 1 and 2 Dimentional data')
raise NotImplementedError(
"The exporter only currently handles 1 and 2 Dimensional data"
)
return datasaver.run_id


Expand All @@ -67,7 +69,9 @@ def store_array_to_database_alt(meas: Measurement, array: DataArray) -> int:
dims = len(array.shape)
assert array.array_id is not None
if dims == 2:
outer_data = np.empty(array.shape[1])
outer_data = np.empty(
array.shape[1] # pyright: ignore[reportGeneralTypeIssues]
)
with meas.run() as datasaver:
for index1, i in enumerate(array.set_arrays[0]):
outer_data[:] = i
Expand All @@ -80,7 +84,9 @@ def store_array_to_database_alt(meas: Measurement, array: DataArray) -> int:
datasaver.add_result((array.set_arrays[0].array_id, i),
(array.array_id, array[index]))
else:
raise NotImplementedError('The exporter only currently handles 1 and 2 Dimentional data')
raise NotImplementedError(
"The exporter only currently handles 1 and 2 Dimensional data"
)
return datasaver.run_id


Expand Down
29 changes: 22 additions & 7 deletions src/qcodes/instrument/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,13 @@ def name_parts(self) -> list[str]:
name_parts.append(self.short_name)
return name_parts

def index(
self, obj: InstrumentModuleType, start: int = 0, stop: int = sys.maxsize
# the parameter obj should be called value but that would
# be an incompatible change
def index( # pyright: ignore[reportIncompatibleMethodOverride]
self,
obj: InstrumentModuleType,
start: int = 0,
stop: int = sys.maxsize,
) -> int:
"""
Return the index of the given object
Expand All @@ -314,7 +319,9 @@ def index(
"""
return self._channels.index(obj, start, stop)

def count(self, obj: InstrumentModuleType) -> int:
def count( # pyright: ignore[reportIncompatibleMethodOverride]
self, obj: InstrumentModuleType
) -> int:
"""Returns number of instances of the given object in the list
Args:
Expand Down Expand Up @@ -625,7 +632,9 @@ def __setitem__(
channel.short_name: channel for channel in self._channels
}

def append(self, obj: InstrumentModuleType) -> None:
def append( # pyright: ignore[reportIncompatibleMethodOverride]
self, obj: InstrumentModuleType
) -> None:
"""
Append a Channel to this list. Requires that the ChannelList is not
locked and that the channel is of the same type as the ones in the list.
Expand Down Expand Up @@ -654,7 +663,9 @@ def clear(self) -> None:
self._channels.clear()
self._channel_mapping.clear()

def remove(self, obj: InstrumentModuleType) -> None:
def remove( # pyright: ignore[reportIncompatibleMethodOverride]
self, obj: InstrumentModuleType
) -> None:
"""
Removes obj from ChannelList if not locked.
Expand All @@ -667,7 +678,9 @@ def remove(self, obj: InstrumentModuleType) -> None:
self._channels.remove(obj)
self._channel_mapping.pop(obj.short_name)

def extend(self, objects: Iterable[InstrumentModuleType]) -> None:
def extend( # pyright: ignore[reportIncompatibleMethodOverride]
self, objects: Iterable[InstrumentModuleType]
) -> None:
"""
Insert an iterable of objects into the list of channels.
Expand All @@ -685,7 +698,9 @@ def extend(self, objects: Iterable[InstrumentModuleType]) -> None:
self._channels.extend(objects_tuple)
self._channel_mapping.update({obj.short_name: obj for obj in objects_tuple})

def insert(self, index: int, obj: InstrumentModuleType) -> None:
def insert( # pyright: ignore[reportIncompatibleMethodOverride]
self, index: int, obj: InstrumentModuleType
) -> None:
"""
Insert an object into the ChannelList at a specific index.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,14 @@ def pre_acquire(self) -> None:
pass

def handle_buffer(
self,
data: np.ndarray,
buffer_number: Optional[int] = None
self, buffer: np.ndarray, buffer_number: Optional[int] = None
) -> None:
"""
See AcquisitionController
:return:
"""
assert self.buffer is not None
self.buffer += data
self.buffer += buffer

def post_acquire(self) -> float:
"""
Expand Down
4 changes: 3 additions & 1 deletion src/qcodes/instrument_drivers/AlazarTech/dll_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ class DllWrapperMeta(type):
# Only allow a single instance per DLL path.
_instances: WeakValueDictionary[str, Any] = WeakValueDictionary()

def __call__(cls, dll_path: str, *args: Any, **kwargs: Any) -> Any:
def __call__( # pyright: ignore[reportIncompatibleMethodOverride]
cls, dll_path: str, *args: Any, **kwargs: Any
) -> Any:
api = cls._instances.get(dll_path, None)
if api is not None:
logger.debug(
Expand Down
4 changes: 2 additions & 2 deletions src/qcodes/instrument_drivers/Keysight/Infiniium.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def setpoints(self) -> Sequence[ParameterBase]:
raise RuntimeError("Invalid type for parent instrument.")

@setpoints.setter
def setpoints(self, val: Any) -> None:
def setpoints(self, setpoints: Any) -> None:
"""
Stub to allow initialization. Ignore any set attempts on setpoint as we
figure it out on the fly.
Expand All @@ -157,7 +157,7 @@ def unit(self) -> str:
return "''"

@unit.setter
def unit(self, val: Any) -> None:
def unit(self, unit: Any) -> None:
"""
Stub to allow initialization.
"""
Expand Down
9 changes: 7 additions & 2 deletions src/qcodes/instrument_drivers/Keysight/Keysight_N9030B.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,15 @@ def get_raw(self) -> ParamRawDataType:
class Trace(ParameterWithSetpoints):
def __init__(self, number: int, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.instrument: (
# the parameter classes should ideally be generic in instrument
# and root instrument classes so we can specialize here.
# for now we have to ignore a type error from pyright
self.instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
KeysightN9030BSpectrumAnalyzerMode | KeysightN9030BPhaseNoiseMode
)
self.root_instrument: KeysightN9030B
self.root_instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
KeysightN9030B
)

self.number = number

Expand Down
7 changes: 6 additions & 1 deletion src/qcodes/instrument_drivers/Keysight/KtM960x.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ def __init__(self, name: str, instrument: "KeysightM960x") -> None:
instrument=instrument,
labels="Measurement Data",
docstring="param that returns measurement values")
self.instrument: "KeysightM960x"
# the parameter classes should ideally be generic in instrument
# and root instrument classes so we can specialize here.
# for now we have to ignore a type error from pyright
self.instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
"KeysightM960x"
)

def get_raw(self) -> tuple[ParamRawDataType, ...]:
return self.instrument._measure()
Expand Down
2 changes: 1 addition & 1 deletion src/qcodes/instrument_drivers/Keysight/N52xx.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def setpoints(self) -> Sequence[ParameterBase]:
raise NotImplementedError(f"Axis for type {sweep_type} not implemented yet")

@setpoints.setter
def setpoints(self, val: Any) -> None:
def setpoints(self, setpoints: Any) -> None:
"""
Stub to allow initialization. Ignore any set attempts on setpoint as we
figure it out on the fly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,9 +461,15 @@ def __init__(self, name: str, instrument: KeysightB1517A, **kwargs: Any):
setpoint_units=(('V',),) * 2,
instrument=instrument,
**kwargs)

self.instrument: KeysightB1517A
self.root_instrument: KeysightB1500
# the parameter classes should ideally be generic in instrument
# and root instrument classes so we can specialize here.
# for now we have to ignore a type error from pyright
self.instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
KeysightB1517A
)
self.root_instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
KeysightB1500
)

self.param1 = _FMTResponse(None, None, None, None)
self.param2 = _FMTResponse(None, None, None, None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,15 @@ class SamplingMeasurement(ParameterWithSetpoints):

def __init__(self, name: str, **kwargs: Any):
super().__init__(name, **kwargs)

self.instrument: "KeysightB1517A"
self.root_instrument: "KeysightB1500"
# the parameter classes should ideally be generic in instrument
# and root instrument classes so we can specialize here.
# for now we have to ignore a type error from pyright
self.instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
"KeysightB1517A"
)
self.root_instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
"KeysightB1500"
)

self.data = _FMTResponse(None, None, None, None)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -884,9 +884,15 @@ def __init__(self, name: str, instrument: KeysightB1520A, **kwargs: Any):
setpoint_units=(('V',),) * 2,
instrument=instrument,
**kwargs)

self.instrument: "KeysightB1520A"
self.root_instrument: "KeysightB1500"
# the parameter classes should ideally be generic in instrument
# and root instrument classes so we can specialize here.
# for now we have to ignore a type error from pyright
self.instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
"KeysightB1520A"
)
self.root_instrument: ( # pyright: ignore[reportIncompatibleMethodOverride]
"KeysightB1500"
)

self.update_name_label_unit_from_impedance_model()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,10 @@ class TimeTrace(ParameterWithSetpoints):
"""

def __init__(self, name: str, instrument: Instrument, **kwargs: Any):

self.instrument: Instrument # needed for mypy
# the parameter classes should ideally be generic in instrument
# and root instrument classes so we can specialize here.
# for now we have to ignore a type error from pyright
self.instrument: Instrument # pyright: ignore[reportIncompatibleMethodOverride]
super().__init__(name=name, instrument=instrument, **kwargs)

# the extra time needed to avoid timeouts during acquisition
Expand Down
6 changes: 3 additions & 3 deletions src/qcodes/instrument_drivers/QDev/QDac_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,9 +687,9 @@ def _wait_and_clear(self, delay: float = 0.5) -> None:
time.sleep(delay)
self.visa_handle.clear()

def connect_message(self,
idn_part: str = "IDN",
being_time: Optional[float] = None) -> None:
def connect_message(
self, idn_param: str = "IDN", begin_time: Optional[float] = None
) -> None:
"""
Override of the standard Instrument class connect_message.
Usually, the response to `*IDN?` is printed. Here, the
Expand Down
35 changes: 20 additions & 15 deletions src/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import annotations

import logging
import time
from functools import partial
from typing import Any, Callable, Optional, Union, cast
from typing import Any, Callable, cast

import numpy as np
import numpy.typing as npt
Expand Down Expand Up @@ -190,7 +192,7 @@ def _param_getter(self, get_cmd: str) -> str:

return resp

def _param_setter(self, set_cmd: str, value: Union[float, str]) -> None:
def _param_setter(self, set_cmd: str, value: float | str) -> None:
"""
General setter function for parameters
Expand Down Expand Up @@ -219,11 +221,14 @@ class OxfordMercuryiPS(VisaInstrument):
supply
"""

def __init__(self, name: str, address: str, visalib: Optional[str] = None,
field_limits: Optional[Callable[[float,
float,
float], bool]] = None,
**kwargs: Any) -> None:
def __init__(
self,
name: str,
address: str,
visalib: str | None = None,
field_limits: Callable[[float, float, float], bool] | None = None,
**kwargs: Any,
) -> None:
"""
Args:
name: The name to give this instrument internally in QCoDeS
Expand Down Expand Up @@ -256,10 +261,6 @@ def __init__(self, name: str, address: str, visalib: Optional[str] = None,

super().__init__(name, address, terminator='\n', visalib=visalib,
**kwargs)

# to ensure a correct snapshot, we must wrap the get function
self.IDN.get = self.IDN._wrap_get(self._idn_getter)

self.firmware = self.IDN()['firmware']

# TODO: Query instrument to ensure which PSUs are actually present
Expand Down Expand Up @@ -351,7 +352,7 @@ def _set_ramp_rate(self, rate: FieldVector) -> None:
self.GRPY.field_ramp_rate(rate.y)
self.GRPZ.field_ramp_rate(rate.z)

def _get_measured(self, coordinates: list[str]) -> Union[float, list[float]]:
def _get_measured(self, coordinates: list[str]) -> float | list[float]:
"""
Get the measured value of a coordinate. Measures all three fields
and computes whatever coordinate we asked for.
Expand Down Expand Up @@ -401,7 +402,7 @@ def _set_target_field(self, field: FieldVector) -> None:
for coord in 'xyz':
self._set_target(coord, field[coord])

def _idn_getter(self) -> dict[str, str]:
def get_idn(self) -> dict[str, str | None]:
"""
Parse the raw non-SCPI compliant IDN string into an IDN dict
Expand All @@ -411,8 +412,12 @@ def _idn_getter(self) -> dict[str, str]:
raw_idn_string = self.ask('*IDN?')
resps = raw_idn_string.split(':')

idn_dict = {'model': resps[2], 'vendor': resps[1],
'serial': resps[3], 'firmware': resps[4]}
idn_dict: dict[str, str | None] = {
"model": resps[2],
"vendor": resps[1],
"serial": resps[3],
"firmware": resps[4],
}

return idn_dict

Expand Down
Loading

0 comments on commit 2943def

Please sign in to comment.