pyvisa / pyvisa-py

A pure python PyVISA backend

Home Page:https://pyvisa-py.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use custom exception types instead of `Exception` for PyVISA-Py backends

chrisgeli opened this issue · comments

Currently, when connecting to an instrument via TCPIP fails, an instance of Exception is raised. This makes it awkward for try/except blocks as all exceptions inherit from that type.

I'm suggesting using errors.VisaIOError instead, or another type specific to PyVISA/PyVISA-Py.

In my case, with a ResourceManager rm = pyvisa.ResourceManager('@py'), it was with a TCPIP instrument and caused the following traceback:

  File "/my_project/test/tester/scope.py", line 51, in __init__
    self.instr = rm.open_resource(visa_resource_name)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my_project/test/tester/.venvs/debian12/lib/python3.11/site-packages/pyvisa/highlevel.py", line 3292, in open_resource
    res.open(access_mode, open_timeout)
  File "/my_project/test/tester/.venvs/debian12/lib/python3.11/site-packages/pyvisa/resources/resource.py", line 281, in open
    self.session, status = self._resource_manager.open_bare_resource(
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my_project/test/tester/.venvs/debian12/lib/python3.11/site-packages/pyvisa/highlevel.py", line 3217, in open_bare_resource
    return self.visalib.open(self.session, resource_name, access_mode, open_timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my_project/test/tester/.venvs/debian12/lib/python3.11/site-packages/pyvisa_py/highlevel.py", line 167, in open
    sess = cls(session, resource_name, parsed, open_timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my_project/test/tester/.venvs/debian12/lib/python3.11/site-packages/pyvisa_py/tcpip.py", line 85, in __new__
    return newcls(resource_manager_session, resource_name, parsed, open_timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my_project/test/tester/.venvs/debian12/lib/python3.11/site-packages/pyvisa_py/sessions.py", line 321, in __init__
    self.after_parsing()
  File "/my_project/test/tester/.venvs/debian12/lib/python3.11/site-packages/pyvisa_py/tcpip.py", line 470, in after_parsing
    raise Exception("error creating link: %d" % error)
Exception: error creating link: 3

To Reproduce

Steps to reproduce the behavior:

  1. In the pyvisa_py folder, run grep 'raise Exception(' *.py
  2. Look at the output, there are several (in my case 2 in serial.py, 1 in sessions.py and 3 in tcpip.py)

Output of pyvisa-info

Machine Details:
   Platform ID:    Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
   Processor:      

Python:
   Implementation: CPython
   Executable:     /my_project/test/tester/.venvs/debian12/bin/python
   Version:        3.11.2
   Compiler:       GCC 12.2.0
   Architecture:   ('x86', 64)
   Build:          Mar 13 2023 12:18:29 (#main)
   Unicode:        UCS4

PyVISA Version: 1.14.1

Backends:
   ivi:
      Version: 1.14.1 (bundled with PyVISA)
      Binary library: Not found
   py:
      Version: 0.7.1
      TCPIP INSTR: Available 
         Resource discovery:
         - VXI-11: partial (psutil not installed)
         - hislip: disabled (zeroconf not installed)
      TCPIP SOCKET: Available 
      ASRL INSTR:
         Please install PySerial (>=3.0) to use this resource type.
         No module named 'serial'
      USB INSTR:
         Please install PyUSB to use this resource type.
         No module named 'usb'
      USB RAW:
         Please install PyUSB to use this resource type.
         No module named 'usb'
      VICP INSTR:
         Please install PyVICP to use this resource type.
      GPIB INSTR:
         Please install linux-gpib (Linux) or gpib-ctypes (Windows, Linux) to use this resource type. Note that installing gpib-ctypes will give you access to a broader range of functionalities.
         No module named 'gpib'
      GPIB INTFC:
         Please install linux-gpib (Linux) or gpib-ctypes (Windows, Linux) to use this resource type. Note that installing gpib-ctypes will give you access to a broader range of functionalities.
         No module named 'gpib'

To work around the issue, I'm currently doing the following:

class ScopeError(RuntimeError):
    pass

class Scope:

    def __init__(self, visa_resource_name: str):
        f'''
        Connects to the specified instrument.
        For information about the visa_resource_name, refer to
        https://pyvisa.readthedocs.io/en/{pyvisa.__version__}/api/resourcemanager.html#pyvisa.highlevel.ResourceManager.open_resource
        '''
        rm = pyvisa.ResourceManager('@py')
        try:
            self.instr = rm.open_resource(visa_resource_name)
        except pyvisa.VisaIOError as e:
            raise ScopeError(f'Could not connect to {visa_resource_name}') from e
        except Exception as e:  # some connection errors are raised as Exception, see https://github.com/pyvisa/pyvisa-py/issues/419
            if len(e.args)==1 and type(e.args[0]) is str and e.args[0].startswith('error creating link: '):
                raise ScopeError(f'Could not connect to {visa_resource_name}') from e
            else:
                raise  # unrecognised exception, simply re-raise

        self.idn = self.instr.query("*IDN?").strip()  # ensure we can communicate

...but it would be nicer if I could remove the except Exception as e branch altogether.