Skip to content

Commit

Permalink
Merge pull request #788 from pyvisa/ruff
Browse files Browse the repository at this point in the history
use ruff as linter and formatter and remove unused setup.py
  • Loading branch information
MatthieuDartiailh committed Nov 27, 2023
2 parents d1604e7 + 23f09e9 commit 3ee8740
Show file tree
Hide file tree
Showing 22 changed files with 129 additions and 136 deletions.
18 changes: 0 additions & 18 deletions .flake8

This file was deleted.

16 changes: 6 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,15 @@ jobs:
- name: Install tools
run: |
python -m pip install --upgrade pip
pip install flake8 black isort mypy pytest numpy
- name: Isort
pip install ruff mypy pytest numpy
- name: Formatting
run: |
isort pyvisa -c;
- name: Black
ruff format pyvisa --check;
- name: Linting
if: always()
run: |
black pyvisa --check;
- name: Flake8
if: always()
run: |
flake8 pyvisa;
- name: Mypy
ruff pyvisa;
- name: typing
if: always()
run: |
mypy pyvisa;
Expand Down
30 changes: 13 additions & 17 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
repos:
- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.10.1
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 6.0.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.1.1 # Use the sha / tag you want to point at
hooks:
- id: mypy
additional_dependencies: [numpy, typing_extensions]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.1.6
hooks:
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.7.0
hooks:
- id: mypy
additional_dependencies: [numpy, typing_extensions]
4 changes: 1 addition & 3 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
black
flake8
ruff
mypy
isort
sphinx
sphinx-rtd-theme
21 changes: 14 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,20 @@ del namedtuple, _version_info, parts
__version__ = "{version}"
"""

[tool.black]
line-length = 88 # Enforce the default value
[tool.ruff]
src = ["src"]
select = ["C", "E", "F", "W", "I", "C90", "RUF"]
extend-exclude = ["pyvisa/thirdparty/*"]
extend-ignore = ["E501", "RUF012"]
line-length = 88

[tool.ruff.isort]
combine-as-imports = true
known-first-party = ["pyvisa"]

[tool.ruff.mccabe]
max-complexity = 20


[tool.pytest.ini_options]
minversion = "6.0"
Expand All @@ -97,8 +109,3 @@ module = [
"pyvisa.thirdparty.*",
]
ignore_errors = true

[tool.isort]
profile = "black"
skip = ["pyvisa/thirdparty/prettytable.py", "pyvisa/__init__.py"]

5 changes: 3 additions & 2 deletions pyvisa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
logger = logging.getLogger("pyvisa")
logger.addHandler(logging.NullHandler())

from .errors import (
# Those import cannot at the top of the file
from .errors import ( # noqa: E402
Error,
InvalidBinaryFormat,
InvalidSession,
Expand All @@ -25,7 +26,7 @@
VisaIOWarning,
VisaTypeError,
)
from .highlevel import ResourceManager
from .highlevel import ResourceManager # noqa: E402
from .resources import Resource # noqa : F401 This is needed to register all resources.


Expand Down
30 changes: 15 additions & 15 deletions pyvisa/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
from . import constants, util

if TYPE_CHECKING:
from .events import Event, IOCompletionEvent # noqa # pragma: no cover
from .resources import Resource # noqa # pragma: no cover
from .events import Event, IOCompletionEvent # pragma: no cover
from .resources import Resource # pragma: no cover

#: Not available value.
NotAvailable = object()
Expand All @@ -58,7 +58,7 @@ class AllSessionTypes: # We use a class to simplify typing
] = defaultdict(set)

#: Map id to attribute
AttributesByID: Dict[int, Type["Attribute"]] = dict()
AttributesByID: Dict[int, Type["Attribute"]] = {}


# --- Descriptor classes ---------------------------------------------------------------
Expand Down Expand Up @@ -160,11 +160,11 @@ def pre_set(self, value: T) -> Any:
def __get__(self, instance: None, owner) -> "Attribute":
pass

@overload # noqa: F811
def __get__(self, instance: Union["Resource", "Event"], owner) -> T: # noqa: F811
@overload
def __get__(self, instance: Union["Resource", "Event"], owner) -> T:
pass

def __get__(self, instance, owner): # noqa: F811
def __get__(self, instance, owner):
"""Access a VISA attribute and convert to a nice Python representation."""
if instance is None:
return self
Expand Down Expand Up @@ -1275,11 +1275,11 @@ class AttrVI_ATTR_TCPIP_HISLIP_VERSION(RangeAttribute):


class AttrVI_ATTR_TCPIP_HISLIP_OVERLAP_EN(BooleanAttribute):
"""Enables HiSLIP Overlap mode.
"""Enables HiSLIP 'Overlap' mode.
The value defaults to the mode suggested by the instrument on HiSLIP connection.
If disabled, the connection uses Synchronous mode to detect and recover
from interrupted errors. If enabled, the connection uses Overlapped mode
If disabled, the connection uses 'Synchronous' mode to detect and recover
from interrupted errors. If enabled, the connection uses 'Overlapped' mode
to allow overlapped responses. If changed, VISA will do a Device Clear
operation to change the mode.
Expand Down Expand Up @@ -2245,7 +2245,7 @@ class AttrVI_ATTR_USB_BULK_OUT_STATUS(RangeAttribute):
class AttrVI_ATTR_USB_BULK_OUT_PIPE(RangeAttribute):
"""Endpoint address of the USB bulk-out or interrupt-out pipe.
An initial value of 1 signifies that this resource does not have any
An initial value of -1 signifies that this resource does not have any
bulk-out or interrupt-out pipes. This endpoint is used in viWrite
and related operations.
Expand Down Expand Up @@ -3347,7 +3347,7 @@ class AttrVI_ATTR_PXI_BUS_NUM(RangeAttribute):
class AttrVI_ATTR_PXI_CHASSIS(RangeAttribute):
"""PXI chassis number of this device.
A value of 1 means the chassis number is unknown.
A value of -1 means the chassis number is unknown.
"""

Expand Down Expand Up @@ -3478,7 +3478,7 @@ class AttrVI_ATTR_PXI_IS_EXPRESS(BooleanAttribute):
class AttrVI_ATTR_PXI_SLOT_LWIDTH(ValuesAttribute):
"""PCI Express link width of the PXI Express peripheral slot of the device.
A value of 1 indicates that the device is not a PXI Express device.
A value of -1 indicates that the device is not a PXI Express device.
"""

Expand All @@ -3500,7 +3500,7 @@ class AttrVI_ATTR_PXI_SLOT_LWIDTH(ValuesAttribute):
class AttrVI_ATTR_PXI_MAX_LWIDTH(ValuesAttribute):
"""Maximum PCI Express link width of the device.
A value of 1 indicates that the device is not a PXI/PCI Express device.
A value of -1 indicates that the device is not a PXI/PCI Express device.
"""

Expand All @@ -3522,7 +3522,7 @@ class AttrVI_ATTR_PXI_MAX_LWIDTH(ValuesAttribute):
class AttrVI_ATTR_PXI_ACTUAL_LWIDTH(ValuesAttribute):
"""PCI Express link width negotiated between the host controller and the device.
A value of 1 indicates that the device is not a PXI/PCI Express device.
A value of -1 indicates that the device is not a PXI/PCI Express device.
"""

Expand All @@ -3544,7 +3544,7 @@ class AttrVI_ATTR_PXI_ACTUAL_LWIDTH(ValuesAttribute):
class AttrVI_ATTR_PXI_DSTAR_BUS(RangeAttribute):
"""Differential star bus number of this device.
A value of 1 means the chassis is unidentified or does not have a timing slot.
A value of -1 means the chassis is unidentified or does not have a timing slot.
"""

Expand Down
2 changes: 1 addition & 1 deletion pyvisa/ctwrapper/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
"peek_64",
]

__all__ = ["visa_functions", "set_signatures"] + visa_functions
__all__ = ["visa_functions", "set_signatures", *visa_functions]

VI_SPEC_VERSION = 0x00300000

Expand Down
2 changes: 1 addition & 1 deletion pyvisa/ctwrapper/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def list_resources(
)
except errors.VisaIOError as e:
if e.error_code == constants.StatusCode.error_resource_not_found:
return tuple()
return ()
raise e

try:
Expand Down
2 changes: 1 addition & 1 deletion pyvisa/ctwrapper/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def _type_pair(ctypes_type):


def _type_triplet(ctypes_type):
return _type_pair(ctypes_type) + (_ctypes.POINTER(ctypes_type),)
return (*_type_pair(ctypes_type), _ctypes.POINTER(ctypes_type))


ViUInt64, ViPUInt64, ViAUInt64 = _type_triplet(_ctypes.c_uint64)
Expand Down
2 changes: 1 addition & 1 deletion pyvisa/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Event:
_context: Optional[VISAEventContext]

#: Maps Event type to Python class encapsulating that event.
_event_classes: ClassVar[Dict[constants.EventType, Type["Event"]]] = dict()
_event_classes: ClassVar[Dict[constants.EventType, Type["Event"]]] = {}

@classmethod
def register(
Expand Down
10 changes: 5 additions & 5 deletions pyvisa/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def __new__(
# Create instance specific registries.
#: Error codes on which to issue a warning.
obj.issue_warning_on = set(errors.default_warnings)
obj._last_status_in_session = dict()
obj._last_status_in_session = {}
obj._ignore_warning_in_session = defaultdict(set)
obj.handlers = defaultdict(list)
obj.resource_manager = None
Expand Down Expand Up @@ -2913,7 +2913,7 @@ class ResourceManager(object):
#: Maps (Interface Type, Resource Class) to Python class encapsulating that resource.
_resource_classes: ClassVar[
Dict[Tuple[constants.InterfaceType, str], Type["Resource"]]
] = dict()
] = {}

#: Session handler for the resource manager.
_session: Optional[VISARMSession] = None
Expand Down Expand Up @@ -3149,10 +3149,10 @@ def list_resources_info(self, query: str = "?*::INSTR") -> Dict[str, ResourceInf
"""

return dict(
(resource, self.resource_info(resource))
return {
resource: self.resource_info(resource)
for resource in self.list_resources(query)
)
}

def list_opened_resources(self) -> List["Resource"]:
"""Return a list of all the opened resources."""
Expand Down
4 changes: 2 additions & 2 deletions pyvisa/rname.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from . import constants, errors, logger

if TYPE_CHECKING:
from .resources import Resource # noqa # pragma: no cover
from .resources import Resource # pragma: no cover

#: Interface types for which a subclass of ResourceName exists
_INTERFACE_TYPES: Set[str] = set()
Expand Down Expand Up @@ -871,7 +871,7 @@ def open_close(resource_name):
for rn in filtered:
with open_close(rn) as getter:
try:
if eval(optional, None, dict(res=getter)):
if eval(optional, None, {"res": getter}):
selected.append(rn)
except Exception:
logger.exception("Failed to evaluate %s on %s", optional, rn)
Expand Down
2 changes: 1 addition & 1 deletion pyvisa/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def print_attribute_list(self):

print(p.get_string(sortby="VISA name"))

def do_attr(self, args): # noqa: C901
def do_attr(self, args):
"""Get or set the state for a visa attribute.
List all attributes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ def test_read_ascii_values(self, msg):
self.instr.write(msg)
self.instr.write("SEND")
values = self.instr.read_ascii_values()
assert type(values[0]) is float
assert isinstance(values[0], float)
assert values == [1.0, 2.0, 3.0, 4.0, 5.0]

# Non standard separator and termination
Expand All @@ -376,7 +376,7 @@ def test_read_ascii_values(self, msg):
"SEND", converter="d", separator=";", delay=0.5
)
assert time.time() - tic > 0.5
assert type(values[0]) is int
assert isinstance(values[0], int)
assert values == [1, 2, 3, 4, 5]

# Numpy container
Expand Down Expand Up @@ -573,7 +573,7 @@ def test_delay_in_query_ascii(self):
tic = time.perf_counter()
values = self.instr.query_ascii_values("SEND")
assert time.perf_counter() - tic > 0.99
assert type(values[0]) is float
assert isinstance(values[0], float)
assert values == [1.0, 2.0, 3.0, 4.0, 5.0]

# Test specifying the delay
Expand All @@ -583,7 +583,7 @@ def test_delay_in_query_ascii(self):
tic = time.perf_counter()
values = self.instr.query_ascii_values("SEND", delay=1.0)
assert time.perf_counter() - tic > 0.99
assert type(values[0]) is float
assert isinstance(values[0], float)
assert values == [1.0, 2.0, 3.0, 4.0, 5.0]

# Test specifying a 0 delay
Expand All @@ -593,7 +593,7 @@ def test_delay_in_query_ascii(self):
tic = time.perf_counter()
values = self.instr.query_ascii_values("SEND", delay=0.0)
assert time.perf_counter() - tic < 0.99
assert type(values[0]) is float
assert isinstance(values[0], float)
assert values == [1.0, 2.0, 3.0, 4.0, 5.0]

def test_instrument_wide_delay_in_query_binary(self):
Expand Down

0 comments on commit 3ee8740

Please sign in to comment.