Skip to content

Commit

Permalink
Merge #547
Browse files Browse the repository at this point in the history
547: highlevel: avoid returning a generic resource info for a non-int board r=MatthieuDartiailh a=MatthieuDartiailh

This typically happens for serial resource on Linux where we end up ASRL/dev/tty0::INSTR. Without this change users have to specify the resource class they want.

- [x] Executed ``black . && isort -c . && flake8`` with no errors
- [x] The change is fully covered by automated unit tests
- [x] Added an entry to the CHANGES file


Co-authored-by: MatthieuDartiailh <marul@laposte.net>
  • Loading branch information
bors[bot] and MatthieuDartiailh committed Sep 23, 2020
2 parents b59e099 + 8c90319 commit 1196571
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 34 deletions.
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
repos:
- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.21
rev: v5.5.3
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: stable
rev: 20.8b1
hooks:
- id: black
language_version: python3.7
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.3
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: '' # Use the sha / tag you want to point at
rev: v0.782 # Use the sha / tag you want to point at
hooks:
- id: mypy
additional_dependencies: [numpy, typing_extensions]
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ PyVISA Changelog

- fix the listing of available backends (Also not that we now return the backend
name as can be used to create a ResourceManger) PR #545
- allow a None value for the board value of a ResourceInfo PR #547
This allows for funky resource name such ASRL/dev/tty0::INSTR which are common
in pyvisa-py and avoid returning a completely generic resource in those cases.

1.11 (16-09-2020)
-----------------
Expand Down
49 changes: 29 additions & 20 deletions pyvisa/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,18 @@
#: Named tuple with information about a resource. Returned by some :class:`ResourceManager` methods.
#:
#: :interface_type: Interface type of the given resource string. :class:`pyvisa.constants.InterfaceType`
#: :interface_board_number: Board number of the interface of the given resource string.
#: :interface_board_number: Board number of the interface of the given resource string. We allow None
#: since serial resources may not sometimes be easily described
#: by a single number in particular on Linux system.
#: :resource_class: Specifies the resource class (for example, "INSTR") of the given resource string.
#: :resource_name: This is the expanded version of the given resource string.
#: The format should be similar to the VISA-defined canonical resource name.
#: The format should be similar to the VISA-defined canonical resource name.
#: :alias: Specifies the user-defined alias for the given resource string.
ResourceInfo = NamedTuple(
"ResourceInfo",
(
("interface_type", constants.InterfaceType),
("interface_board_number", int),
("interface_board_number", Optional[int]),
("resource_class", Optional[str]),
("resource_name", Optional[str]),
("alias", Optional[str]),
Expand Down Expand Up @@ -2036,29 +2038,36 @@ def parse_resource_extended(
"""
try:
parsed = rname.parse_resource_name(resource_name)

return (
ResourceInfo(
parsed.interface_type_const,
# We can only get concrete classes which have one of those
# attributes
int(
parsed.board # type: ignore
if hasattr(parsed, "board")
else parsed.interface # type: ignore
),
parsed.resource_class,
str(parsed),
None,
),
StatusCode.success,
)
except ValueError:
return (
ResourceInfo(constants.InterfaceType.unknown, 0, None, None, None),
StatusCode.error_invalid_resource_name,
)

board_number: Optional[int]
try:
# We can only get concrete classes which have one of those attributes
board_number = int(
parsed.board # type: ignore
if hasattr(parsed, "board")
else parsed.interface # type: ignore
)
# In some cases the board number may not be convertible to an int
# PyVISA-py serial resources on Linux for example
except ValueError:
board_number = None

return (
ResourceInfo(
parsed.interface_type_const,
board_number,
parsed.resource_class,
str(parsed),
None,
),
StatusCode.success,
)

def peek_8(
self, session: VISASession, address: VISAMemoryAddress
) -> Tuple[int, StatusCode]:
Expand Down
42 changes: 33 additions & 9 deletions pyvisa/testsuite/test_highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,50 @@ class TestHighlevel(BaseTestCase):

CHECK_NO_WARNING = False

def test_base_class_parse_resource(self):
@pytest.mark.parametrize(
"rsc_name, values",
[
("TCPIP::192.168.0.1::INSTR", (constants.InterfaceType.tcpip, 0, "INSTR")),
("TCPIP1::192.168.0.1::INSTR", (constants.InterfaceType.tcpip, 1, "INSTR")),
(
"TCPIP::192.168.0.1::5000::SOCKET",
(constants.InterfaceType.tcpip, 0, "SOCKET"),
),
(
"TCPIP2::192.168.0.1::5000::SOCKET",
(constants.InterfaceType.tcpip, 2, "SOCKET"),
),
("GPIB::1::INSTR", (constants.InterfaceType.gpib, 0, "INSTR")),
("GPIB::INTFC", (constants.InterfaceType.gpib, 0, "INTFC")),
("GPIB2::1::INSTR", (constants.InterfaceType.gpib, 2, "INSTR")),
("GPIB3::INTFC", (constants.InterfaceType.gpib, 3, "INTFC")),
(
"USB1::0x1111::0x2222::0x4445::0::RAW",
(constants.InterfaceType.usb, 1, "RAW"),
),
(
"USB0::0x1112::0x2223::0x1234::0::INSTR",
(constants.InterfaceType.usb, 0, "INSTR"),
),
("ASRL2::INSTR", (constants.InterfaceType.asrl, 2, "INSTR")),
("ASRL/dev/tty0::INSTR", (constants.InterfaceType.asrl, None, "INSTR")),
],
)
def test_base_class_parse_resource(self, rsc_name, values):
"""Test the base class implementation of parse_resource."""
lib = highlevel.VisaLibraryBase("test")
rsc_name = "TCPIP::192.168.0.1::INSTR"
info, ret_code = lib.parse_resource(None, rsc_name)

# interface_type interface_board_number resource_class resource_name alias
for parsed, value in zip(
info, (constants.InterfaceType.tcpip, 0, None, None, None)
):
for parsed, value in zip(info, values[:2] + (None, None, None)):
assert parsed == value

info, ret_code = lib.parse_resource_extended(None, rsc_name)
# interface_type interface_board_number resource_class resource_name alias
for parsed, value in zip(
info,
(
constants.InterfaceType.tcpip,
0,
"INSTR",
values
+ (
rname.to_canonical_name(rsc_name),
None,
),
Expand Down

0 comments on commit 1196571

Please sign in to comment.