Skip to content
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

Run pyright with standard checks #5721

Merged
merged 21 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b862017
enable standard mode for pyright
jenshnielsen Feb 3, 2024
398727f
InstrumentModule/Channel rename args to match ABC
jenshnielsen Feb 3, 2024
85add0c
NumpyJSONEncoder update argument name to match parrent class
jenshnielsen Feb 3, 2024
cfeece6
rename stub method / unused args to match parrent class
jenshnielsen Feb 3, 2024
43502d9
Silence warnings about incorrect specilization
jenshnielsen Feb 3, 2024
d4c7e81
Alazar rename to match parent class
jenshnielsen Feb 3, 2024
fac811f
alazar ignore a warning about one argument made explicit
jenshnielsen Feb 3, 2024
ac545c6
make get_raw a proper method on the instrument (expect when using Com…
jenshnielsen Feb 3, 2024
c401df3
fix incompatibe override in test fixtures
jenshnielsen Feb 3, 2024
a8f53d5
silence mypy errors about overriding methods
jenshnielsen Feb 3, 2024
0df5ba9
add some todos
jenshnielsen Feb 3, 2024
16639cf
Fix issue in fixtures
jenshnielsen Feb 3, 2024
7a30459
restore python 3.9 compatibility
jenshnielsen Feb 3, 2024
646f1cd
make set / set_raw propper methods
jenshnielsen Feb 4, 2024
20decd4
Ensure that set_raw sets the value of a manual parameter
jenshnielsen Feb 4, 2024
5ce10eb
typecheck with pyright 1.1.351
jenshnielsen Feb 26, 2024
5129d95
update docstrings to reflect change
jenshnielsen Feb 26, 2024
f9fa4ff
Clarify todo
jenshnielsen Feb 26, 2024
d9ec916
revert changes to channel
jenshnielsen Mar 4, 2024
c324777
ignore override warnings in channel
jenshnielsen Mar 4, 2024
b2a94b6
add changes for 5721
jenshnielsen Mar 4, 2024
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
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
Loading