Skip to content

Commit

Permalink
style: Update linting rules. (#132)
Browse files Browse the repository at this point in the history
* ci: Add explicit disable of a new pyright rule.
* style: Updated all type ignore comments to include specific error codes.
* style: Updated code to pass more ruff style checks for pathlib usage.
* style: Updated code to always use timezones when working with datetime objects.
  • Loading branch information
nfelt14 authored Jan 24, 2024
1 parent 86ad11b commit 357f061
Show file tree
Hide file tree
Showing 49 changed files with 176 additions and 173 deletions.
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def prep_jinja_env(jinja_env: JinjaEnvironment) -> None:
Args:
jinja_env: The Jinja environment.
"""
jinja_env.tests["contains"] = item_in_sequence # pyright: ignore
jinja_env.tests["contains"] = item_in_sequence # pyright: ignore[reportArgumentType,reportUnknownMemberType]


# FUTURE: # autoapi_prepare_jinja_env = prep_jinja_env
Expand Down Expand Up @@ -228,4 +228,4 @@ def setup(sphinx: Sphinx) -> None:
Args:
sphinx: The sphinx object.
"""
sphinx.connect("autoapi-skip-member", skip_member) # pyright: ignore
sphinx.connect("autoapi-skip-member", skip_member) # pyright: ignore[reportUnknownMemberType]
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
READING_COUNT = int(float(inst.commands.buffer_var["defbuffer1"].n))
for x in range(1, READING_COUNT + 1):
# Voltage readings are in defbuffer1.
timestamp_data.append( # type: ignore
timestamp_data.append( # pyright: ignore[reportUnknownMemberType]
inst.commands.buffer_var["defbuffer1"].relativetimestamps[x]
)
buffer1_data.append(inst.commands.buffer_var["defbuffer1"].readings[x]) # type: ignore
buffer1_data.append(inst.commands.buffer_var["defbuffer1"].readings[x]) # pyright: ignore[reportUnknownMemberType]

print(f"{x}, {timestamp_data[x-1]}, {buffer1_data[x-1]}")
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@
READING_COUNT = int(float(smu2450.commands.buffer_var["defbuffer1"].n))
for x in range(1, READING_COUNT + 1):
# Voltage readings are in defbuffer1.
timestamp_data.append( # type: ignore
timestamp_data.append( # pyright: ignore[reportUnknownMemberType]
smu2450.commands.buffer_var["defbuffer1"].timestamps[x]
)
buffer1_data.append(smu2450.commands.buffer_var["defbuffer1"].readings[x]) # type: ignore
buffer1_data.append(smu2450.commands.buffer_var["defbuffer1"].readings[x]) # pyright: ignore[reportUnknownMemberType]

print(f"{timestamp_data[x-1]}, {buffer1_data[x-1]}")
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
READING_COUNT = int(float(inst.commands.buffer_var["defbuffer1"].n))
for x in range(1, READING_COUNT + 1):
# Resistance readings are in defbuffer1.
timestamp_data.append( # type:ignore
timestamp_data.append( # pyright: ignore[reportUnknownMemberType]
inst.commands.buffer_var["defbuffer1"].timestamps[x]
)
buffer1_data.append(inst.commands.buffer_var["defbuffer1"].readings[x]) # type:ignore
buffer1_data.append(inst.commands.buffer_var["defbuffer1"].readings[x]) # pyright: ignore[reportUnknownMemberType]

print(f"{timestamp_data[x-1]}, {buffer1_data[x-1]}")
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
reading = inst.commands.buffer_var["defbuffer1"].readings[i]
source_value = inst.commands.buffer_var["defbuffer1"].sourcevalues[i]
timestamp = float(
inst.commands.buffer_var["defbuffer1"].relativetimestamps.get[i] # type: ignore
inst.commands.buffer_var["defbuffer1"].relativetimestamps.get(i) # pyright: ignore[reportArgumentType]
)
print(i, reading, source_value, timestamp)

Expand Down
4 changes: 2 additions & 2 deletions examples/source_measure_units/2400/smu_2460_pulse_train.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@
inst.commands.trigger.model.setblock_trigger_block_config_recall(4, "OutputList")
inst.commands.trigger.model.setblock_trigger_block_delay_constant(
5,
MEASURE_DELAY, # type: ignore
MEASURE_DELAY, # type: ignore[arg-type]
)
inst.commands.trigger.model.setblock_trigger_block_measure_digitize(6)
inst.commands.trigger.model.setblock_trigger_block_wait(7, "trigger.EVENT_TIMER2")
inst.commands.trigger.model.setblock_trigger_block_config_next(8, "OutputList")
inst.commands.trigger.model.setblock_trigger_block_branch_counter(9, POINTS, 3) # type: ignore
inst.commands.trigger.model.setblock_trigger_block_branch_counter(9, POINTS, 3) # type: ignore[arg-type]
inst.commands.trigger.model.setblock_trigger_block_source_output(10, inst.commands.smu.OFF)

# Start the trigger model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ def diode_test(inst: SMU2602B) -> None:

if SPEED == "FAST":
inst.commands.display.clear()
inst.commands.display.setcursor(1, 1) # type: ignore
inst.commands.display.setcursor(1, 1) # type: ignore[arg-type]
inst.commands.display.settext("Test In Progress")
inst.commands.display.setcursor(2, 1) # type: ignore
inst.commands.display.setcursor(2, 1) # type: ignore[arg-type]
inst.commands.display.settext(f"Testing {NDIODES} Parts")

start_time = time.time()
Expand Down
9 changes: 6 additions & 3 deletions examples/source_measure_units/2600/smu_2651_fast_adc_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
Converted to Python tm_devices script. DCA 4.12.23
"""
from datetime import date
from datetime import datetime

from dateutil.tz import tzlocal

from tm_devices import DeviceManager
from tm_devices.drivers import SMU2651A

TODAY_DATE = datetime.now(tz=tzlocal()).date()
RESOURCE_ID = "192.168.0.1"
V_FILENAME = "CapturePulseV_" + str(date.today()) + ".csv"
I_FILENAME = "CapturePulseI_" + str(date.today()) + ".csv"
V_FILENAME = "CapturePulseV_" + str(TODAY_DATE) + ".csv"
I_FILENAME = "CapturePulseI_" + str(TODAY_DATE) + ".csv"

# TEST CONSTANTS
NUM_PULSES = 5
Expand Down
20 changes: 11 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ ignore = [
pythonPlatform = "All"
pythonVersion = "3.8"
reportCallInDefaultInitializer = "error"
reportImplicitOverride = "none" # this check is not needed
# TODO: turn on the check for implicit string concatenation
reportImplicitStringConcatenation = "none" # this is allowed by this project's formatting standard
reportImportCycles = "none" # other analysis tools catch these more effectively
Expand Down Expand Up @@ -282,21 +283,21 @@ ignore = [
"ANN102", # Missing type annotation for cls in method
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed in *args and **kwargs
"COM812", # Trailing comma missing
"DTZ", # flake8-datetimez # TODO: enable this later
"EM102", # Exception must not use an f-string literal, assign to variable first
"FA100", # Missing `from __future__ import annotations`, but uses ... # TODO: enable this later
"FA100", # Missing `from __future__ import annotations`, but uses ...
"FBT", # flake8-boolean-trap
"FIX002", # Line contains TODO
"FIX002", # Line contains TO DO
"ISC001", # single-line-implicit-string-concatenation (handled by formatter)
"PGH003", # Use specific rule codes when ignoring type issues # TODO: enable this later
"PTH", # flake8-use-pathlib # TODO: enable this later
"PTH109", # `os.getcwd()` should be replaced by `Path.cwd()`
"PTH123", # `open()` should be replaced by `Path.open()`
"PTH207", # Replace `iglob` with `Path.glob` or `Path.rglob`
"PYI021", # Docstrings should not be included in stubs
"T20", # flake8-print
"TD002", # Missing author in TODO; try: `# TODO(<author_name>): ...` # TODO: enable this later
"TD003", # Missing issue link on the line following this TODO # TODO: enable this later
"TD002", # Missing author in TO DO
"TD003", # Missing issue link on the line following this TO DO
"TRY301", # Abstract raise to an inner function
"UP006", # Use {to} instead of {from} for type annotation # TODO: enable this later
"UP007", # Use `X | Y` for type annotations # TODO: enable this later
"UP006", # Use {to} instead of {from} for type annotation
"UP007", # Use `X | Y` for type annotations
"UP024", # Replace aliased errors with `OSError`
"UP037" # Remove quotes from type annotation
]
Expand Down Expand Up @@ -348,6 +349,7 @@ order-by-type = false
"tests/**" = [
"PLC1901", # compare-to-empty-string
"PLR2004", # Magic value used in comparison
"PTH107", # `os.remove()` should be replaced by `Path.unlink()`
"S101" # Use of assert detected
]
"tests/samples/golden_stubs/**" = [
Expand Down
17 changes: 11 additions & 6 deletions scripts/contributor_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
This script will run through the commands listed in the CONTRIBUTING.md file.
"""
from __future__ import annotations

import argparse
import glob
import os
Expand Down Expand Up @@ -43,26 +45,29 @@ def running_in_virtualenv() -> bool:
return sys.prefix != sys.base_prefix


def create_virtual_environment(virtual_env_dir: str, reset_env: bool) -> None:
def create_virtual_environment(
virtual_env_dir: Union[str, os.PathLike[str]], reset_env: bool
) -> None:
"""Create a virtual environment.
Args:
virtual_env_dir: The directory where the virtual environment should be created
reset_env: Indicate if the virtual environment should be completely reset
"""
virtual_env_dir = Path(virtual_env_dir)
added_newline = False
if (
reset_env
and os.path.exists(virtual_env_dir)
and not sys.prefix.startswith(virtual_env_dir)
and virtual_env_dir.exists()
and not sys.prefix.startswith(str(virtual_env_dir.resolve()))
and not running_in_virtualenv()
):
if not added_newline:
added_newline = True
print("")
print(f"Removing virtualenv located at '{virtual_env_dir}'")
shutil.rmtree(virtual_env_dir)
if not os.path.exists(virtual_env_dir) and not running_in_virtualenv():
if not virtual_env_dir.exists() and not running_in_virtualenv():
if not added_newline:
print("")
print(f"Creating virtualenv located at '{virtual_env_dir}'")
Expand Down Expand Up @@ -113,8 +118,8 @@ def main() -> None:

# Delete the previous poetry lock file
lock_file = Path(starting_dir) / "poetry.lock"
if os.path.exists(lock_file):
os.remove(lock_file)
if lock_file.exists():
lock_file.unlink()

# Find the python executable from the new virtual environment
files = list(
Expand Down
3 changes: 1 addition & 2 deletions scripts/project_version.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
"""This script modifies or gets the current project version in the pyproject.toml file."""
import argparse
import os.path
import pathlib

import tomli
import tomli_w

from poetry.core.constraints.version import Version

PYPROJECT_FILE = pathlib.Path(f"{os.path.dirname(__file__)}/../pyproject.toml")
PYPROJECT_FILE = pathlib.Path(f"{pathlib.Path(__file__).parent}/../pyproject.toml")


def parse_arguments() -> argparse.Namespace:
Expand Down
2 changes: 1 addition & 1 deletion scripts/update_development_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from pathlib import Path
from typing import List

from yamlfix import fix_files # pyright: ignore
from yamlfix import fix_files # pyright: ignore[reportUnknownVariableType]

from pypi_latest_version import get_latest_version

Expand Down
6 changes: 3 additions & 3 deletions src/tm_devices/commands/_helpers/generic_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class NoDeviceProvidedError(Exception):
####################################################################################################
# Classes
####################################################################################################
class DefaultDictPassKeyToFactory(defaultdict): # type: ignore
class DefaultDictPassKeyToFactory(defaultdict): # pyright: ignore[reportMissingTypeArgument]
"""A custom defaultdict.
This custom defaultdict passes the key used to access a missing value into the stored
Expand All @@ -41,7 +41,7 @@ def __init__(self, default_factory: Callable[[Union[int, str]], Any], **kwargs:
default_factory: The factory function used to create new values in the dictionary.
kwargs: The keyword arguments.
"""
super().__init__(default_factory, **kwargs) # type: ignore
super().__init__(default_factory, **kwargs) # type: ignore[arg-type]

def __missing__(self, key: Any) -> Any:
"""Call the ``default_factory()`` function and pass the key as the only parameter.
Expand All @@ -51,7 +51,7 @@ def __missing__(self, key: Any) -> Any:
"""
if self.default_factory:
# noinspection PyArgumentList # pylint: disable=not-callable
dict.__setitem__(self, key, self.default_factory(key)) # type: ignore
dict.__setitem__(self, key, self.default_factory(key)) # type: ignore[arg-type]
return cast(Any, self[key])
return cast(Any, super().__missing__(key)) # pyright: ignore [reportUnknownMemberType]

Expand Down
2 changes: 1 addition & 1 deletion src/tm_devices/commands/_helpers/scpi_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ def __init__(self, device: Optional["PIDevice"], cmd_syntax: str) -> None:
raise ValueError(msg)


class DefaultDictDeviceCommunication(defaultdict): # type: ignore
class DefaultDictDeviceCommunication(defaultdict): # pyright: ignore[reportMissingTypeArgument]
"""A custom default dictionary that can be used to send/receive commands to/from a device.
The ``.query()`` method is used when ``__getitem__()`` is called and the result of the query is
Expand Down
2 changes: 1 addition & 1 deletion src/tm_devices/components/dm_config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ def __parse_config_file(
KeyError: Indicates unrecognized option name.
"""
config_path = pathlib.Path(config_file_path) # normalize the path
if not os.path.isfile(config_path):
if not config_path.is_file():
raise FileNotFoundError(config_path)
# read in data
with open(config_path, encoding="utf-8") as config_file:
Expand Down
19 changes: 11 additions & 8 deletions src/tm_devices/device_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,13 @@
warnings.simplefilter("ignore", UserWarning)
import pyvisa as visa

from pyvisa_py.protocols.rpc import RPCError # type: ignore
from pyvisa_py.protocols.rpc import RPCError # pyright: ignore[reportMissingTypeStubs]

# noinspection PyUnresolvedReferences # pylint: disable=unused-import,wrong-import-order
from traceback_with_variables import activate_by_import # noqa: F401 # type: ignore
# pylint: disable=unused-import,wrong-import-order
# noinspection PyUnresolvedReferences
from traceback_with_variables import ( # pyright: ignore[reportMissingTypeStubs]
activate_by_import, # noqa: F401 # pyright: ignore[reportUnusedImport]
)

if TYPE_CHECKING:
from pyvisa.resources import MessageBasedResource
Expand All @@ -154,7 +157,7 @@
# TODO: this is temporary until python3.12 which will support TypeVar with defaults
AFGAlias: TypeAlias = Union[AFG3K, AFG3KB, AFG3KC, AFG31K]
AWGAlias: TypeAlias = Union[AWG5K, AWG5KB, AWG5KC, AWG7K, AWG7KB, AWG7KC, AWG5200, AWG70KA, AWG70KB]
DataAcquisitionSystemAlias: TypeAlias = Union[DAQ6510] # pyright: ignore
DataAcquisitionSystemAlias: TypeAlias = Union[DAQ6510] # pyright: ignore[reportInvalidTypeArguments]
DigitalMultimeterAlias: TypeAlias = Union[DMM6500, DMM7510, DMM7512]
ScopeAlias: TypeAlias = Union[
DPO5K,
Expand Down Expand Up @@ -199,7 +202,7 @@
MSO70KC,
MSO70KDX,
]
MarginTesterAlias: TypeAlias = Union[TMT4] # pyright: ignore
MarginTesterAlias: TypeAlias = Union[TMT4] # pyright: ignore[reportInvalidTypeArguments]
PowerSupplyUnitAlias: TypeAlias = Union[
PSU2200,
PSU2220,
Expand Down Expand Up @@ -243,7 +246,7 @@
SMU6514,
SMU6517B,
]
SystemsSwitchAlias: TypeAlias = Union[SS3706A] # pyright: ignore
SystemsSwitchAlias: TypeAlias = Union[SS3706A] # pyright: ignore[reportInvalidTypeArguments]


####################################################################################################
Expand Down Expand Up @@ -1209,7 +1212,7 @@ def _add_device( # noqa: PLR0913
config_dict["serial_config"] = serial_config
if device_driver:
config_dict["device_driver"] = device_driver
new_device_name, new_device_config = self.__config.add_device(**config_dict) # type: ignore
new_device_name, new_device_config = self.__config.add_device(**config_dict) # pyright: ignore[reportArgumentType]

return self.__create_device(new_device_name, new_device_config)

Expand Down Expand Up @@ -1361,7 +1364,7 @@ def __protect_access(self) -> None:
AttributeError: Indicates that the calling method should not have been used.
"""
if not self.__is_open and not self._suppress_protection:
previous_frame = cast(FrameType, inspect.currentframe().f_back.f_back) # type: ignore
previous_frame = cast(FrameType, inspect.currentframe().f_back.f_back) # pyright: ignore[reportOptionalMemberAccess]
message = (
f"The {self.__class__.__name__} is closed, please use the .open() "
f"method before continuing to use the {self.__class__.__name__}.\n"
Expand Down
2 changes: 1 addition & 1 deletion src/tm_devices/driver_mixins/class_extension_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def add_property(
... # pragma: no cover

@classmethod
def add_property( # type: ignore
def add_property( # pyright: ignore[reportInconsistentOverload]
cls: Type[_EM],
method: Optional[Callable[[_EM], _T]] = None,
/,
Expand Down
2 changes: 1 addition & 1 deletion src/tm_devices/drivers/api/rest_api/margin_testers/tmt4.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def wait_till_unlocked(self, timeout: int = 120) -> None:
start = time.time()
while time.time() < start + timeout:
_, res_json, _, _ = self.get("/device/status", allow_errors=True)
if res_json["usage"] == "NOT LOCKED": # type: ignore
if res_json["usage"] == "NOT LOCKED": # pyright: ignore[reportArgumentType,reportCallIssue]
return
time.sleep(1)
msg = f"waited more than {timeout} seconds for {self.name} to unlock"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def all_channel_names_list(self) -> Tuple[str, ...]:
@property
def ieee_cmds(self) -> LegacyTSPIEEE4882Commands:
"""Return an internal class containing methods for the standard IEEE 488.2 command set."""
return self._ieee_cmds # type: ignore
return self._ieee_cmds # pyright: ignore[reportReturnType]

@ReadOnlyCachedProperty
def total_channels(self) -> int:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ def _reboot(self) -> None:
"""
# TODO: implement
raise NotImplementedError(
f"``.{inspect.currentframe().f_code.co_name}()``" # pyright: ignore
f"``.{inspect.currentframe().f_code.co_name}()``" # pyright: ignore[reportOptionalMemberAccess]
f" is not yet implemented for the {self.__class__.__name__} driver"
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ def _reboot(self) -> None:
"""
# TODO: implement
raise NotImplementedError(
f"``.{inspect.currentframe().f_code.co_name}()``" # pyright: ignore
f"``.{inspect.currentframe().f_code.co_name}()``" # pyright: ignore[reportOptionalMemberAccess]
f" is not yet implemented for the {self.__class__.__name__} driver"
)
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def all_channel_names_list(self) -> Tuple[str, ...]:
@property
def ieee_cmds(self) -> LegacyTSPIEEE4882Commands:
"""Return an internal class containing methods for the standard IEEE 488.2 command set."""
return self._ieee_cmds # type: ignore
return self._ieee_cmds # pyright: ignore[reportReturnType]

################################################################################################
# Public Methods
Expand Down
Loading

0 comments on commit 357f061

Please sign in to comment.