1# -*- coding: utf-8 -*-
2"""High level Visa library wrapper.
3
4This file is part of PyVISA.
5
6:copyright: 2014-2020 by PyVISA Authors, see AUTHORS for more details.
7:license: MIT, see LICENSE for more details.
8
9"""
10import atexit
11import contextlib
12import copy
13import os
14import pkgutil
15import warnings
16from collections import defaultdict
17from importlib import import_module
18from itertools import chain
19from types import ModuleType
20from typing import (
21    TYPE_CHECKING,
22    Any,
23    Callable,
24    ContextManager,
25    Dict,
26    Iterable,
27    Iterator,
28    List,
29    NamedTuple,
30    Optional,
31    Set,
32    SupportsBytes,
33    Tuple,
34    Type,
35    TypeVar,
36    Union,
37    cast,
38)
39from weakref import WeakMethod, WeakSet, WeakValueDictionary
40
41from typing_extensions import ClassVar, DefaultDict, Literal
42
43from . import attributes, constants, errors, logger, rname
44from .constants import StatusCode
45from .typing import (
46    VISAEventContext,
47    VISAHandler,
48    VISAJobID,
49    VISAMemoryAddress,
50    VISARMSession,
51    VISASession,
52)
53from .util import LibraryPath
54
55if TYPE_CHECKING:
56    from .resources import Resource  # pragma: no cover
57
58#: Resource extended information
59#:
60#: Named tuple with information about a resource. Returned by some :class:`ResourceManager` methods.
61#:
62#: :interface_type: Interface type of the given resource string. :class:`pyvisa.constants.InterfaceType`
63#: :interface_board_number: Board number of the interface of the given resource string. We allow None
64#:                          since serial resources may not sometimes be easily described
65#:                          by a single number in particular on Linux system.
66#: :resource_class: Specifies the resource class (for example, "INSTR") of the given resource string.
67#: :resource_name: This is the expanded version of the given resource string.
68#:                 The format should be similar to the VISA-defined canonical resource name.
69#: :alias: Specifies the user-defined alias for the given resource string.
70ResourceInfo = NamedTuple(
71    "ResourceInfo",
72    (
73        ("interface_type", constants.InterfaceType),
74        ("interface_board_number", Optional[int]),
75        ("resource_class", Optional[str]),
76        ("resource_name", Optional[str]),
77        ("alias", Optional[str]),
78    ),
79)
80
81# Used to properly type the __new__ method
82T = TypeVar("T", bound="VisaLibraryBase")
83
84
85class VisaLibraryBase(object):
86    """Base for VISA library classes.
87
88    A class derived from `VisaLibraryBase` library provides the low-level communication
89    to the underlying devices providing Pythonic wrappers to VISA functions. But not all
90    derived class must/will implement all methods. Even if methods are expected to return
91    the status code they are expected to raise the appropriate exception when an error
92    ocurred since this is more Pythonic.
93
94    The default VisaLibrary class is :class:`pyvisa.ctwrapper.highlevel.IVIVisaLibrary`,
95    which implements a ctypes wrapper around the IVI-VISA library.
96    Certainly, IVI-VISA can be NI-VISA, Keysight VISA, R&S VISA, tekVISA etc.
97
98    In general, you should not instantiate it directly. The object exposed to the user
99    is the :class:`pyvisa.highlevel.ResourceManager`. If needed, you can access the
100    VISA library from it::
101
102        >>> import pyvisa
103        >>> rm = pyvisa.ResourceManager("/path/to/my/libvisa.so.7")
104        >>> lib = rm.visalib
105
106    """
107
108    #: Default ResourceManager instance for this library.
109    resource_manager: Optional["ResourceManager"]
110
111    #: Path to the VISA library used by this instance
112    library_path: LibraryPath
113
114    #: Maps library path to VisaLibrary object
115    _registry: ClassVar[
116        Dict[Tuple[Type["VisaLibraryBase"], LibraryPath], "VisaLibraryBase"]
117    ] = WeakValueDictionary()  # type: ignore
118
119    #: Last return value of the library.
120    _last_status: StatusCode = StatusCode(0)
121
122    #: Maps session handle to last status.
123    _last_status_in_session: Dict[
124        Union[VISASession, VISARMSession, VISAEventContext], StatusCode
125    ]
126
127    #: Maps session handle to warnings to ignore.
128    _ignore_warning_in_session: Dict[int, set]
129
130    #: Extra inforatoion used for logging errors
131    _logging_extra: Dict[str, str]
132
133    #: Contains all installed event handlers.
134    #: Its elements are tuples with four elements: The handler itself (a Python
135    #: callable), the user handle (in any format making sense to the lower level
136    #: implementation, ie as a ctypes object for the ctypes backend) and the
137    #: handler again, this time in a format meaningful to the backend (ie as a
138    #: ctypes object created with CFUNCTYPE for the ctypes backend) and
139    #: the event type.
140    handlers: DefaultDict[VISASession, List[Tuple[VISAHandler, Any, Any, Any]]]
141
142    #: Set error codes on which to issue a warning.
143    issue_warning_on: Set[StatusCode]
144
145    def __new__(
146        cls: Type[T], library_path: Union[str, LibraryPath] = ""
147    ) -> "VisaLibraryBase":
148        """Create a new VISA library from the specified path.
149
150        If a library was already created using the same path and class this
151        library object is returned instead.
152
153        Parameters
154        ----------
155        library_path : str | LibraryPath
156            Path to the VISA library to use in the backend.
157
158        Raises
159        ------
160        OSError
161            Raised if the VISA library object could not be created.
162
163        """
164        if library_path == "":
165            errs = []
166            for path in cls.get_library_paths():
167                try:
168                    return cls(path)
169                except OSError as e:
170                    logger.debug("Could not open VISA library %s: %s", path, str(e))
171                    errs.append(str(e))
172                except Exception as e:
173                    errs.append(str(e))
174            else:
175                raise OSError("Could not open VISA library:\n" + "\n".join(errs))
176
177        if not isinstance(library_path, LibraryPath):
178            lib_path = LibraryPath(library_path, "user specified")
179        else:
180            lib_path = library_path
181
182        if (cls, lib_path) in cls._registry:
183            return cls._registry[(cls, lib_path)]
184
185        obj = super(VisaLibraryBase, cls).__new__(cls)
186
187        obj.library_path = lib_path
188
189        obj._logging_extra = {"library_path": obj.library_path}
190
191        obj._init()
192
193        # Create instance specific registries.
194        #: Error codes on which to issue a warning.
195        obj.issue_warning_on = set(errors.default_warnings)
196        obj._last_status_in_session = dict()
197        obj._ignore_warning_in_session = defaultdict(set)
198        obj.handlers = defaultdict(list)
199        obj.resource_manager = None
200
201        logger.debug("Created library wrapper for %s", lib_path)
202
203        cls._registry[(cls, lib_path)] = obj
204
205        return obj
206
207    @staticmethod
208    def get_library_paths() -> Iterable[LibraryPath]:
209        """Override to list the possible library_paths if no path is specified."""
210        return ()
211
212    @staticmethod
213    def get_debug_info() -> Union[Iterable[str], Dict[str, Union[str, Dict[str, Any]]]]:
214        """Override to return an iterable of lines with the backend debug details."""
215        return ["Does not provide debug info"]
216
217    def _init(self) -> None:
218        """Override this method to customize VisaLibrary initialization."""
219        pass
220
221    def __str__(self) -> str:
222        """str representation of the library."""
223        return "Visa Library at %s" % self.library_path
224
225    def __repr__(self) -> str:
226        """str representation of the library including the type of the library."""
227        return "<%s(%r)>" % (type(self).__name__, self.library_path)
228
229    def handle_return_value(
230        self,
231        session: Optional[Union[VISAEventContext, VISARMSession, VISASession]],
232        status_code: int,
233    ) -> StatusCode:
234        """Helper function handling the return code of a low-level operation.
235
236        Used when implementing concrete subclasses of VISALibraryBase.
237
238        """
239        rv: StatusCode
240        try:
241            rv = StatusCode(status_code)
242        except ValueError:
243            rv = cast(StatusCode, status_code)
244
245        self._last_status = rv
246
247        if session is not None:
248            self._last_status_in_session[session] = rv
249
250        if rv < 0:
251            raise errors.VisaIOError(rv)
252
253        if rv in self.issue_warning_on:
254            if session and rv not in self._ignore_warning_in_session[session]:
255                warnings.warn(errors.VisaIOWarning(rv), stacklevel=2)
256
257        # Return the original value for further processing.
258        return rv
259
260    @property
261    def last_status(self) -> StatusCode:
262        """Last return value of the library."""
263        return self._last_status
264
265    def get_last_status_in_session(
266        self, session: Union[VISASession, VISARMSession]
267    ) -> StatusCode:
268        """Last status in session.
269
270        Helper function to be called by resources properties.
271
272        """
273        try:
274            return self._last_status_in_session[session]
275        except KeyError:
276            raise errors.Error(
277                "The session %r does not seem to be valid as it does not have any last status"
278                % session
279            )
280
281    @contextlib.contextmanager
282    def ignore_warning(
283        self,
284        session: Union[VISASession, VISARMSession],
285        *warnings_constants: StatusCode,
286    ) -> Iterator:
287        """Ignore warnings for a session for the duration of the context.
288
289        Parameters
290        ----------
291        session : Union[VISASession, VISARMSession]
292            Unique logical identifier to a session.
293        warnings_constants : StatusCode
294            Constants identifying the warnings to ignore.
295
296        """
297        self._ignore_warning_in_session[session].update(warnings_constants)
298        yield
299        self._ignore_warning_in_session[session].difference_update(warnings_constants)
300
301    def install_visa_handler(
302        self,
303        session: VISASession,
304        event_type: constants.EventType,
305        handler: VISAHandler,
306        user_handle: Any = None,
307    ) -> Any:
308        """Installs handlers for event callbacks.
309
310        Parameters
311        ----------
312        session : VISASession
313            Unique logical identifier to a session.
314        event_type : constants.EventType,
315            Logical event identifier.
316        handler : VISAHandler
317            Handler to be installed by a client application.
318        user_handle :
319            A value specified by an application that can be used for identifying
320            handlers uniquely for an event type.
321
322        Returns
323        -------
324        converted_user_handle:
325            Converted user handle to match the underlying library. This version
326            of the handle should be used in further call to the library.
327
328        """
329        try:
330            new_handler = self.install_handler(
331                session, event_type, handler, user_handle
332            )
333        except TypeError as e:
334            raise errors.VisaTypeError(str(e)) from e
335
336        self.handlers[session].append(new_handler[:-1] + (event_type,))
337        return new_handler[1]
338
339    def uninstall_visa_handler(
340        self,
341        session: VISASession,
342        event_type: constants.EventType,
343        handler: VISAHandler,
344        user_handle: Any = None,
345    ) -> None:
346        """Uninstalls handlers for events.
347
348        Parameters
349        ----------
350        session : VISASession
351            Unique logical identifier to a session.
352        event_type : constants.EventType
353            Logical event identifier.
354        handler : VISAHandler
355            Handler to be uninstalled by a client application.
356        user_handle :
357            The user handle returned by install_visa_handler.
358
359        """
360        for ndx, element in enumerate(self.handlers[session]):
361            # use == rather than is to allow bound methods as handlers
362            if (
363                element[0] == handler
364                and element[1] is user_handle
365                and element[3] == event_type
366            ):
367                del self.handlers[session][ndx]
368                break
369        else:
370            raise errors.UnknownHandler(event_type, handler, user_handle)
371        self.uninstall_handler(session, event_type, element[2], user_handle)
372
373    def __uninstall_all_handlers_helper(self, session: VISASession) -> None:
374        """Uninstall all VISA handlers for a given session."""
375        for element in self.handlers[session]:
376            self.uninstall_handler(session, element[3], element[2], element[1])
377        del self.handlers[session]
378
379    def uninstall_all_visa_handlers(self, session: Optional[VISASession]) -> None:
380        """Uninstalls all previously installed handlers for a particular session.
381
382        Parameters
383        ----------
384        session : VISASession | None
385            Unique logical identifier to a session. If None, operates on all sessions.
386
387        """
388
389        if session is not None:
390            self.__uninstall_all_handlers_helper(session)
391        else:
392            for session in list(self.handlers):
393                self.__uninstall_all_handlers_helper(session)
394
395    def read_memory(
396        self,
397        session: VISASession,
398        space: constants.AddressSpace,
399        offset: int,
400        width: Union[Literal[8, 16, 32, 64], constants.DataWidth],
401        extended: bool = False,
402    ) -> Tuple[int, StatusCode]:
403        """Read a value from the specified memory space and offset.
404
405        Corresponds to viIn* functions of the VISA library.
406
407        Parameters
408        ----------
409        session : VISASession
410            Unique logical identifier to a session.
411        space : constants.AddressSpace
412            Specifies the address space from which to read.
413        offset : int
414            Offset (in bytes) of the address or register from which to read.
415        width : Union[Literal[8, 16, 32, 64], constants.DataWidth]
416            Number of bits to read (8, 16, 32 or 64).
417        extended : bool, optional
418            Use 64 bits offset independent of the platform.
419
420        Returns
421        -------
422        data : int
423            Data read from memory
424        status_code : StatusCode
425            Return value of the library call.
426
427        Raises
428        ------
429        ValueError
430            Raised if an invalid width is specified.
431
432        """
433        w = width * 8 if isinstance(width, constants.DataWidth) else width
434        if w not in (8, 16, 32, 64):
435            raise ValueError(
436                "%s is not a valid size. Valid values are 8, 16, 32 or 64 "
437                "or one member of constants.DataWidth" % width
438            )
439        return getattr(self, f"in_{w}")(session, space, offset, extended)
440
441    def write_memory(
442        self,
443        session: VISASession,
444        space: constants.AddressSpace,
445        offset: int,
446        data: int,
447        width: Union[Literal[8, 16, 32, 64], constants.DataWidth],
448        extended: bool = False,
449    ) -> StatusCode:
450        """Write a value to the specified memory space and offset.
451
452        Parameters
453        ----------
454        session : VISASession
455            Unique logical identifier to a session.
456        space : constants.AddressSpace
457            Specifies the address space.
458        offset : int
459            Offset (in bytes) of the address or register from which to read.
460        data : int
461            Data to write to bus.
462        width : Union[Literal[8, 16, 32, 64], constants.DataWidth]
463            Number of bits to read.
464        extended : bool, optional
465            Use 64 bits offset independent of the platform, by default False.
466
467        Returns
468        -------
469        StatusCode
470            Return value of the library call.
471
472        Raises
473        ------
474        ValueError
475            Raised if an invalid width is specified.
476
477        """
478        w = width * 8 if isinstance(width, constants.DataWidth) else width
479        if w not in (8, 16, 32, 64):
480            raise ValueError(
481                "%s is not a valid size. Valid values are 8, 16, 32 or 64 "
482                "or one member of constants.DataWidth" % width
483            )
484        return getattr(self, f"out_{w}")(session, space, offset, data, extended)
485
486    def move_in(
487        self,
488        session: VISASession,
489        space: constants.AddressSpace,
490        offset: int,
491        length: int,
492        width: Union[Literal[8, 16, 32, 64], constants.DataWidth],
493        extended: bool = False,
494    ) -> Tuple[List[int], StatusCode]:
495        """Move a block of data to local memory from the given address space and offset.
496
497        Corresponds to viMoveIn* functions of the VISA library.
498
499        Parameters
500        ----------
501        session : VISASession
502            Unique logical identifier to a session.
503        space : constants.AddressSpace
504            Address space from which to move the data.
505        offset : int
506            Offset (in bytes) of the address or register from which to read.
507        length : int
508             Number of elements to transfer, where the data width of
509             the elements to transfer is identical to the source data width.
510        width : Union[Literal[8, 16, 32, 64], constants.DataWidth]
511            Number of bits to read per element.
512        extended : bool, optional
513            Use 64 bits offset independent of the platform, by default False.
514
515        Returns
516        -------
517        data : List[int]
518            Data read from the bus
519        status_code : StatusCode
520            Return value of the library call.
521
522        Raises
523        ------
524        ValueError
525            Raised if an invalid width is specified.
526
527        """
528        w = width * 8 if isinstance(width, constants.DataWidth) else width
529        if w not in (8, 16, 32, 64):
530            raise ValueError(
531                "%s is not a valid size. Valid values are 8, 16, 32 or 64 "
532                "or one member of constants.DataWidth" % width
533            )
534        return getattr(self, f"move_in_{w}")(session, space, offset, length, extended)
535
536    def move_out(
537        self,
538        session: VISASession,
539        space: constants.AddressSpace,
540        offset: int,
541        length: int,
542        data: Iterable[int],
543        width: Union[Literal[8, 16, 32, 64], constants.DataWidth],
544        extended: bool = False,
545    ) -> StatusCode:
546        """Move a block of data from local memory to the given address space and offset.
547
548        Corresponds to viMoveOut* functions of the VISA library.
549
550        Parameters
551        ----------
552        session : VISASession
553            Unique logical identifier to a session.
554        space : constants.AddressSpace
555            Address space into which move the data.
556        offset : int
557            Offset (in bytes) of the address or register from which to read.
558        length : int
559            Number of elements to transfer, where the data width of
560            the elements to transfer is identical to the source data width.
561        data : Iterable[int]
562            Data to write to bus.
563        width : Union[Literal[8, 16, 32, 64], constants.DataWidth]
564            Number of bits to per element.
565        extended : bool, optional
566            Use 64 bits offset independent of the platform, by default False.
567
568        Returns
569        -------
570        StatusCode
571            Return value of the library call.
572
573        Raises
574        ------
575        ValueError
576            Raised if an invalid width is specified.
577
578        """
579        w = width * 8 if isinstance(width, constants.DataWidth) else width
580        if w not in (8, 16, 32, 64):
581            raise ValueError(
582                "%s is not a valid size. Valid values are 8, 16, 32 or 64 "
583                "or one member of constants.DataWidth" % width
584            )
585        return getattr(self, f"move_out_{w}")(
586            session, space, offset, length, data, extended
587        )
588
589    def peek(
590        self,
591        session: VISASession,
592        address: VISAMemoryAddress,
593        width: Union[Literal[8, 16, 32, 64], constants.DataWidth],
594    ) -> Tuple[int, StatusCode]:
595        """Read an 8, 16, 32, or 64-bit value from the specified address.
596
597        Corresponds to viPeek* functions of the VISA library.
598
599        Parameters
600        ----------
601        session : VISASession
602            Unique logical identifier to a session.
603        address : VISAMemoryAddress
604            Source address to read the value.
605        width : Union[Literal[8, 16, 32, 64], constants.DataWidth]
606            Number of bits to read.
607
608        Returns
609        -------
610        data : int
611            Data read from bus
612        status_code : StatusCode
613            Return value of the library call.
614
615        Raises
616        ------
617        ValueError
618            Raised if an invalid width is specified.
619
620        """
621        w = width * 8 if isinstance(width, constants.DataWidth) else width
622        if w not in (8, 16, 32, 64):
623            raise ValueError(
624                "%s is not a valid size. Valid values are 8, 16, 32 or 64 "
625                "or one member of constants.DataWidth" % width
626            )
627        return getattr(self, f"peek_{w}")(session, address)
628
629    def poke(
630        self,
631        session: VISASession,
632        address: VISAMemoryAddress,
633        width: Union[Literal[8, 16, 32, 64], constants.DataWidth],
634        data: int,
635    ) -> StatusCode:
636        """Writes an 8, 16, 32, or 64-bit value from the specified address.
637
638        Corresponds to viPoke* functions of the VISA library.
639
640        Parameters
641        ----------
642        session : VISASession
643            Unique logical identifier to a session.
644        address : VISAMemoryAddress
645            Source address to read the value.
646        width : Union[Literal[8, 16, 32, 64], constants.DataWidth]
647            Number of bits to read.
648        data : int
649            Data to write to the bus
650
651        Returns
652        -------
653        status_code : StatusCode
654            Return value of the library call.
655
656        Raises
657        ------
658        ValueError
659            Raised if an invalid width is specified.
660
661        """
662        w = width * 8 if isinstance(width, constants.DataWidth) else width
663        if w not in (8, 16, 32, 64):
664            raise ValueError(
665                "%s is not a valid size. Valid values are 8, 16, 32 or 64 "
666                "or one member of constants.DataWidth" % width
667            )
668        return getattr(self, f"poke_{w}")(session, address, data)
669
670    # Methods that VISA Library implementations must implement
671
672    def assert_interrupt_signal(
673        self,
674        session: VISASession,
675        mode: constants.AssertSignalInterrupt,
676        status_id: int,
677    ) -> StatusCode:
678        """Asserts the specified interrupt or signal.
679
680        Corresponds to viAssertIntrSignal function of the VISA library.
681
682        Parameters
683        ----------
684        session : VISASession
685            Unique logical identifier to a session.
686        mode : constants.AssertSignalInterrupt
687            How to assert the interrupt.
688        status_id : int
689            Status value to be presented during an interrupt acknowledge cycle.
690
691        Returns
692        -------
693        StatusCode
694            Return value of the library call.
695
696        """
697        raise NotImplementedError
698
699    def assert_trigger(
700        self, session: VISASession, protocol: constants.TriggerProtocol
701    ) -> StatusCode:
702        """Assert software or hardware trigger.
703
704        Corresponds to viAssertTrigger function of the VISA library.
705
706        Parameters
707        ----------
708        session : VISASession
709            Unique logical identifier to a session.
710        protocol : constants.TriggerProtocol
711            Trigger protocol to use during assertion.
712
713        Returns
714        -------
715        StatusCode
716            Return value of the library call.
717
718        """
719        raise NotImplementedError
720
721    def assert_utility_signal(
722        self, session: VISASession, line: constants.UtilityBusSignal
723    ) -> StatusCode:
724        """Assert or deassert the specified utility bus signal.
725
726        Corresponds to viAssertUtilSignal function of the VISA library.
727
728        Parameters
729        ----------
730        session : VISASession
731            Unique logical identifier to a session.
732        line : constants.UtilityBusSignal
733            Specifies the utility bus signal to assert.
734
735        Returns
736        -------
737        StatusCode
738            Return value of the library call.
739
740        """
741        raise NotImplementedError
742
743    def buffer_read(self, session: VISASession, count: int) -> Tuple[bytes, StatusCode]:
744        """Reads data through the use of a formatted I/O read buffer.
745
746        The data can be read from a device or an interface.
747
748        Corresponds to viBufRead function of the VISA library.
749
750        Parameters
751        ----------
752        session : VISASession\
753            Unique logical identifier to a session.
754        count : int
755            Number of bytes to be read.
756
757        Returns
758        -------
759        dbytes
760            Data read
761        StatusCode
762            Return value of the library call.
763
764        """
765        raise NotImplementedError
766
767    def buffer_write(self, session: VISASession, data: bytes) -> Tuple[int, StatusCode]:
768        """Writes data to a formatted I/O write buffer synchronously.
769
770        Corresponds to viBufWrite function of the VISA library.
771
772        Parameters
773        ----------
774        session : VISASession
775            Unique logical identifier to a session.
776        data : bytes
777            Data to be written.
778
779        Returns
780        -------
781        int
782            number of written bytes
783        StatusCode
784            return value of the library call.
785
786        """
787        raise NotImplementedError
788
789    def clear(self, session: VISASession) -> StatusCode:
790        """Clears a device.
791
792        Corresponds to viClear function of the VISA library.
793
794        Parameters
795        ----------
796        session : VISASession
797            Unique logical identifier to a session.
798
799        Returns
800        -------
801        StatusCode
802            Return value of the library call.
803
804        """
805        raise NotImplementedError
806
807    def close(
808        self, session: Union[VISASession, VISAEventContext, VISARMSession]
809    ) -> StatusCode:
810        """Closes the specified session, event, or find list.
811
812        Corresponds to viClose function of the VISA library.
813
814        Parameters
815        ---------
816        session : Union[VISASession, VISAEventContext, VISARMSession]
817            Unique logical identifier to a session, event, resource manager.
818
819        Returns
820        -------
821        StatusCode
822            Return value of the library call.
823
824        """
825        raise NotImplementedError
826
827    def disable_event(
828        self,
829        session: VISASession,
830        event_type: constants.EventType,
831        mechanism: constants.EventMechanism,
832    ) -> StatusCode:
833        """Disable notification for an event type(s) via the specified mechanism(s).
834
835        Corresponds to viDisableEvent function of the VISA library.
836
837        Parameters
838        ----------
839        session : VISASession
840            Unique logical identifier to a session.
841        event_type : constants.EventType
842            Event type.
843        mechanism : constants.EventMechanism
844            Event handling mechanisms to be disabled.
845
846        Returns
847        -------
848        StatusCode
849            Return value of the library call.
850
851        """
852        raise NotImplementedError
853
854    def discard_events(
855        self,
856        session: VISASession,
857        event_type: constants.EventType,
858        mechanism: constants.EventMechanism,
859    ) -> StatusCode:
860        """Discard event occurrences for a given type and mechanisms in a session.
861
862        Corresponds to viDiscardEvents function of the VISA library.
863
864        Parameters
865        ----------
866        session : VISASession
867            Unique logical identifier to a session.
868        event_type : constans.EventType
869            Logical event identifier.
870        mechanism : constants.EventMechanism
871            Specifies event handling mechanisms to be discarded.
872
873        Returns
874        -------
875        StatusCode
876            Return value of the library call.
877
878        """
879        raise NotImplementedError
880
881    def enable_event(
882        self,
883        session: VISASession,
884        event_type: constants.EventType,
885        mechanism: constants.EventMechanism,
886        context: None = None,
887    ) -> StatusCode:
888        """Enable event occurrences for specified event types and mechanisms in a session.
889
890        Corresponds to viEnableEvent function of the VISA library.
891
892        Parameters
893        ----------
894        session : VISASession
895            Unique logical identifier to a session.
896        event_type : constants.EventType
897            Logical event identifier.
898        mechanism : constants.EventMechanism
899            Specifies event handling mechanisms to be enabled.
900        context : None, optional
901            Unused parameter...
902
903        Returns
904        -------
905        StatusCode
906            Return value of the library call.
907
908        """
909        raise NotImplementedError
910
911    def flush(
912        self, session: VISASession, mask: constants.BufferOperation
913    ) -> StatusCode:
914        """Flush the specified buffers.
915
916        The buffers can be associated with formatted I/O operations and/or
917        serial communication.
918
919        Corresponds to viFlush function of the VISA library.
920
921        Parameters
922        ----------
923        session : VISASession
924            Unique logical identifier to a session.
925        mask : constants.BufferOperation
926            Specifies the action to be taken with flushing the buffer.
927            The values can be combined using the | operator. However multiple
928            operations on a single buffer cannot be combined.
929
930        Returns
931        -------
932        StatusCode
933            Return value of the library call.
934
935        """
936        raise NotImplementedError
937
938    def get_attribute(
939        self,
940        session: Union[VISASession, VISAEventContext, VISARMSession],
941        attribute: Union[constants.ResourceAttribute, constants.EventAttribute],
942    ) -> Tuple[Any, StatusCode]:
943        """Retrieves the state of an attribute.
944
945        Corresponds to viGetAttribute function of the VISA library.
946
947        Parameters
948        ----------
949        session : Union[VISASession, VISAEventContext]
950            Unique logical identifier to a session, event, or find list.
951        attribute : Union[constants.ResourceAttribute, constants.EventAttribute]
952            Resource or event attribute for which the state query is made.
953
954        Returns
955        -------
956        Any
957            State of the queried attribute for a specified resource
958        StatusCode
959            Return value of the library call.
960
961        """
962        raise NotImplementedError
963
964    def gpib_command(self, session: VISASession, data: bytes) -> Tuple[int, StatusCode]:
965        """Write GPIB command bytes on the bus.
966
967        Corresponds to viGpibCommand function of the VISA library.
968
969        Parameters
970        ----------
971        session : VISASession
972            Unique logical identifier to a session.
973        data : bytes
974            Data to write.
975
976        Returns
977        -------
978        int
979            Number of written bytes
980        StatusCode
981            Return value of the library call.
982
983        """
984        raise NotImplementedError
985
986    def gpib_control_atn(
987        self, session: VISASession, mode: constants.ATNLineOperation
988    ) -> StatusCode:
989        """Specifies the state of the ATN line and the local active controller state.
990
991        Corresponds to viGpibControlATN function of the VISA library.
992
993        Parameters
994        ----------
995        session : VISASession
996            Unique logical identifier to a session.
997        mode : constants.ATNLineOperation
998            State of the ATN line and optionally the local active controller state.
999
1000        Returns
1001        -------
1002        StatusCode
1003            Return value of the library call.
1004
1005        """
1006        raise NotImplementedError
1007
1008    def gpib_control_ren(
1009        self, session: VISASession, mode: constants.RENLineOperation
1010    ) -> StatusCode:
1011        """Controls the state of the GPIB Remote Enable (REN) interface line.
1012
1013        Optionally the remote/local state of the device can also be set.
1014
1015        Corresponds to viGpibControlREN function of the VISA library.
1016
1017        Parameters
1018        ----------
1019        session : VISASession
1020            Unique logical identifier to a session.
1021        mode : constants.RENLineOperation
1022            State of the REN line and optionally the device remote/local state.
1023
1024        Returns
1025        -------
1026        StatusCode
1027            Return value of the library call.
1028
1029        """
1030        raise NotImplementedError
1031
1032    def gpib_pass_control(
1033        self, session: VISASession, primary_address: int, secondary_address: int
1034    ) -> StatusCode:
1035        """Tell a GPIB device to become controller in charge (CIC).
1036
1037        Corresponds to viGpibPassControl function of the VISA library.
1038
1039        Parameters
1040        ----------
1041        session : VISASession
1042            Unique logical identifier to a session.
1043        primary_address : int
1044            Primary address of the GPIB device to which you want to pass control.
1045        secondary_address : int
1046            Secondary address of the targeted GPIB device.
1047            If the targeted device does not have a secondary address, this parameter
1048            should contain the value Constants.VI_NO_SEC_ADDR.
1049
1050        Returns
1051        -------
1052        StatusCode
1053            Return value of the library call.
1054
1055        """
1056        raise NotImplementedError
1057
1058    def gpib_send_ifc(self, session: VISASession) -> StatusCode:
1059        """Pulse the interface clear line (IFC) for at least 100 microseconds.
1060
1061        Corresponds to viGpibSendIFC function of the VISA library.
1062
1063        Parameters
1064        ----------
1065        session : VISASession
1066            Unique logical identifier to a session.
1067
1068        Returns
1069        -------
1070        StatusCode
1071            Return value of the library call.
1072
1073        """
1074        raise NotImplementedError
1075
1076    def in_8(
1077        self,
1078        session: VISASession,
1079        space: constants.AddressSpace,
1080        offset: int,
1081        extended: bool = False,
1082    ) -> Tuple[int, StatusCode]:
1083        """Reads in an 8-bit value from the specified memory space and offset.
1084
1085        Corresponds to viIn8* function of the VISA library.
1086
1087        Parameters
1088        ----------
1089        session : VISASession
1090            Unique logical identifier to a session.
1091        space : constants.AddressSpace
1092            Specifies the address space.
1093        offset : int
1094            Offset (in bytes) of the address or register from which to read.
1095        extended : bool, optional
1096            Use 64 bits offset independent of the platform, False by default.
1097
1098        Returns
1099        -------
1100        int
1101            Data read from memory
1102        StatusCode
1103            Return value of the library call.
1104
1105        """
1106        raise NotImplementedError
1107
1108    def in_16(
1109        self,
1110        session: VISASession,
1111        space: constants.AddressSpace,
1112        offset: int,
1113        extended: bool = False,
1114    ) -> Tuple[int, StatusCode]:
1115        """Reads in an 16-bit value from the specified memory space and offset.
1116
1117        Corresponds to viIn16* function of the VISA library.
1118
1119        Parameters
1120        ----------
1121        session : VISASession
1122            Unique logical identifier to a session.
1123        space : constants.AddressSpace
1124            Specifies the address space.
1125        offset : int
1126            Offset (in bytes) of the address or register from which to read.
1127        extended : bool, optional
1128            Use 64 bits offset independent of the platform, False by default.
1129
1130        Returns
1131        -------
1132        int
1133            Data read from memory
1134        StatusCode
1135            Return value of the library call.
1136
1137        """
1138        raise NotImplementedError
1139
1140    def in_32(
1141        self,
1142        session: VISASession,
1143        space: constants.AddressSpace,
1144        offset: int,
1145        extended: bool = False,
1146    ) -> Tuple[int, StatusCode]:
1147        """Reads in an 32-bit value from the specified memory space and offset.
1148
1149        Corresponds to viIn32* function of the VISA library.
1150
1151        Parameters
1152        ----------
1153        session : VISASession
1154            Unique logical identifier to a session.
1155        space : constants.AddressSpace
1156            Specifies the address space.
1157        offset : int
1158            Offset (in bytes) of the address or register from which to read.
1159        extended : bool, optional
1160            Use 64 bits offset independent of the platform, False by default.
1161
1162        Returns
1163        -------
1164        int
1165            Data read from memory
1166        StatusCode
1167            Return value of the library call.
1168
1169        """
1170        raise NotImplementedError
1171
1172    def in_64(
1173        self,
1174        session: VISASession,
1175        space: constants.AddressSpace,
1176        offset: int,
1177        extended: bool = False,
1178    ) -> Tuple[int, StatusCode]:
1179        """Reads in an 64-bit value from the specified memory space and offset.
1180
1181        Corresponds to viIn64* function of the VISA library.
1182
1183        Parameters
1184        ----------
1185        session : VISASession
1186            Unique logical identifier to a session.
1187        space : constants.AddressSpace
1188            Specifies the address space.
1189        offset : int
1190            Offset (in bytes) of the address or register from which to read.
1191        extended : bool, optional
1192            Use 64 bits offset independent of the platform, False by default.
1193
1194        Returns
1195        -------
1196        int
1197            Data read from memory
1198        StatusCode
1199            Return value of the library call.
1200
1201        """
1202        raise NotImplementedError
1203
1204    def install_handler(
1205        self,
1206        session: VISASession,
1207        event_type: constants.EventType,
1208        handler: VISAHandler,
1209        user_handle: Any,
1210    ) -> Tuple[VISAHandler, Any, Any, StatusCode]:
1211        """Install handlers for event callbacks.
1212
1213        Corresponds to viInstallHandler function of the VISA library.
1214
1215        Parameters
1216        ----------
1217        session : VISASession
1218            Unique logical identifier to a session.
1219        event_type : constants.EventType
1220            Logical event identifier.
1221        handler : VISAHandler
1222            Reference to a handler to be installed by a client application.
1223        user_handle : Any
1224            Value specified by an application that can be used for identifying
1225            handlers uniquely for an event type.
1226
1227        Returns
1228        -------
1229        handler : VISAHandler
1230            Handler to be installed by a client application.
1231        converted_user_handle :
1232            Converted user handle to match the underlying library. This version
1233            of the handle should be used in further call to the library.
1234        converted_handler :
1235            Converted version of the handler satisfying to backend library.
1236        status_code : StatusCode
1237            Return value of the library call
1238
1239        """
1240        raise NotImplementedError
1241
1242    def list_resources(
1243        self, session: VISARMSession, query: str = "?*::INSTR"
1244    ) -> Tuple[str, ...]:
1245        """Return a tuple of all connected devices matching query.
1246
1247        Parameters
1248        ----------
1249        session : VISARMSession
1250            Unique logical identifier to the resource manager session.
1251        query : str
1252            Regular expression used to match devices.
1253
1254        Returns
1255        -------
1256        Tuple[str, ...]
1257            Resource names of all the connected devices matching the query.
1258
1259        """
1260        raise NotImplementedError
1261
1262    def lock(
1263        self,
1264        session: VISASession,
1265        lock_type: constants.Lock,
1266        timeout: int,
1267        requested_key: Optional[str] = None,
1268    ) -> Tuple[str, StatusCode]:
1269        """Establishes an access mode to the specified resources.
1270
1271        Corresponds to viLock function of the VISA library.
1272
1273        Parameters
1274        ----------
1275        session : VISASession
1276            Unique logical identifier to a session.
1277        lock_type : constants.Lock
1278            Specifies the type of lock requested.
1279        timeout : int
1280            Absolute time period (in milliseconds) that a resource waits to get
1281            unlocked by the locking session before returning an error.
1282        requested_key : Optional[str], optional
1283            Requested locking key in the case of a shared lock. For an exclusive
1284            lock it should be None.
1285
1286        Returns
1287        -------
1288        Optional[str]
1289            Key that can then be passed to other sessions to share the lock, or
1290            None for an exclusive lock.
1291        StatusCode
1292            Return value of the library call.
1293
1294        """
1295        raise NotImplementedError
1296
1297    def map_address(
1298        self,
1299        session: VISASession,
1300        map_space: constants.AddressSpace,
1301        map_base: int,
1302        map_size: int,
1303        access: Literal[False] = False,
1304        suggested: Optional[int] = None,
1305    ) -> Tuple[int, StatusCode]:
1306        """Maps the specified memory space into the process's address space.
1307
1308        Corresponds to viMapAddress function of the VISA library.
1309
1310        Parameters
1311        ----------
1312        session : VISASession
1313            Unique logical identifier to a session.
1314        map_space : constants.AddressSpace
1315            Specifies the address space to map.
1316        map_base : int
1317            Offset (in bytes) of the memory to be mapped.
1318        map_size : int
1319            Amount of memory to map (in bytes).
1320        access : False
1321            Unused parameter.
1322        suggested : Optional[int], optional
1323            If not None, the operating system attempts to map the memory to the
1324            address specified. There is no guarantee, however, that the memory
1325            will be mapped to that address. This operation may map the memory
1326            into an address region different from the suggested one.
1327
1328        Returns
1329        -------
1330        int
1331            Address in your process space where the memory was mapped
1332        StatusCode
1333            Return value of the library call.
1334
1335        """
1336        raise NotImplementedError
1337
1338    def map_trigger(
1339        self,
1340        session: VISASession,
1341        trigger_source: constants.InputTriggerLine,
1342        trigger_destination: constants.OutputTriggerLine,
1343        mode: None = None,
1344    ) -> StatusCode:
1345        """Map the specified trigger source line to the specified destination line.
1346
1347        Corresponds to viMapTrigger function of the VISA library.
1348
1349        Parameters
1350        ----------
1351        session : VISASession
1352            Unique logical identifier to a session.
1353        trigger_source : constants.InputTriggerLine
1354            Source line from which to map.
1355        trigger_destination : constants.OutputTriggerLine
1356            Destination line to which to map.
1357        mode : None, optional
1358            Always None for this version of the VISA specification.
1359
1360        Returns
1361        -------
1362        StatusCode
1363            Return value of the library call.
1364
1365        """
1366        raise NotImplementedError
1367
1368    def memory_allocation(
1369        self, session: VISASession, size: int, extended: bool = False
1370    ) -> Tuple[int, StatusCode]:
1371        """Allocate memory from a resource's memory region.
1372
1373        Corresponds to viMemAlloc* functions of the VISA library.
1374
1375        Parameters
1376        ----------
1377        session : VISASession
1378            Unique logical identifier to a session.
1379        size : int
1380            Specifies the size of the allocation.
1381        extended : bool, optional
1382            Use 64 bits offset independent of the platform.
1383
1384        Returns
1385        -------
1386        int
1387            offset of the allocated memory
1388        StatusCode
1389            Return value of the library call.
1390
1391        """
1392        raise NotImplementedError
1393
1394    def memory_free(
1395        self, session: VISASession, offset: int, extended: bool = False
1396    ) -> StatusCode:
1397        """Frees memory previously allocated using the memory_allocation() operation.
1398
1399        Corresponds to viMemFree* function of the VISA library.
1400
1401        Parameters
1402        ----------
1403        session : VISASession
1404            Unique logical identifier to a session.
1405        offset : int
1406            Offset of the memory to free.
1407        extended : bool, optional
1408            Use 64 bits offset independent of the platform.
1409
1410        Returns
1411        -------
1412        StatusCode
1413            Return value of the library call.
1414
1415        """
1416        raise NotImplementedError
1417
1418    def move(
1419        self,
1420        session: VISASession,
1421        source_space: constants.AddressSpace,
1422        source_offset: int,
1423        source_width: constants.DataWidth,
1424        destination_space: constants.AddressSpace,
1425        destination_offset: int,
1426        destination_width: constants.DataWidth,
1427        length: int,
1428    ) -> StatusCode:
1429        """Moves a block of data.
1430
1431        Corresponds to viMove function of the VISA library.
1432
1433        Parameters
1434        ----------
1435        session : VISASession
1436            Unique logical identifier to a session.
1437        source_space : constants.AddressSpace
1438            Specifies the address space of the source.
1439        source_offset : int
1440            Offset of the starting address or register from which to read.
1441        source_width : constants.DataWidth
1442            Specifies the data width of the source.
1443        destination_space : constants.AddressSpace
1444            Specifies the address space of the destination.
1445        destination_offset : int
1446            Offset of the starting address or register to which to write.
1447        destination_width : constants.DataWidth
1448            Specifies the data width of the destination.
1449        length: int
1450            Number of elements to transfer, where the data width of the
1451            elements to transfer is identical to the source data width.
1452
1453        Returns
1454        -------
1455        StatusCode
1456            Return value of the library call.
1457
1458        """
1459        raise NotImplementedError
1460
1461    def move_asynchronously(
1462        self,
1463        session: VISASession,
1464        source_space: constants.AddressSpace,
1465        source_offset: int,
1466        source_width: constants.DataWidth,
1467        destination_space: constants.AddressSpace,
1468        destination_offset: int,
1469        destination_width: constants.DataWidth,
1470        length: int,
1471    ) -> Tuple[VISAJobID, StatusCode]:
1472        """Moves a block of data asynchronously.
1473
1474        Corresponds to viMoveAsync function of the VISA library.
1475
1476        Parameters
1477        ----------
1478        session : VISASession
1479            Unique logical identifier to a session.
1480        source_space : constants.AddressSpace
1481            Specifies the address space of the source.
1482        source_offset : int
1483            Offset of the starting address or register from which to read.
1484        source_width : constants.DataWidth
1485            Specifies the data width of the source.
1486        destination_space : constants.AddressSpace
1487            Specifies the address space of the destination.
1488        destination_offset : int
1489            Offset of the starting address or register to which to write.
1490        destination_width : constants.DataWidth
1491            Specifies the data width of the destination.
1492        length : int
1493            Number of elements to transfer, where the data width of the
1494            elements to transfer is identical to the source data width.
1495
1496        Returns
1497        -------
1498        VISAJobID
1499            Job identifier of this asynchronous move operation
1500        StatusCode
1501            Return value of the library call.
1502
1503        """
1504        raise NotImplementedError
1505
1506    def move_in_8(
1507        self,
1508        session: VISASession,
1509        space: constants.AddressSpace,
1510        offset: int,
1511        length: int,
1512        extended: bool = False,
1513    ) -> Tuple[List[int], StatusCode]:
1514        """Moves an 8-bit block of data to local memory.
1515
1516        Corresponds to viMoveIn8* functions of the VISA library.
1517
1518        Parameters
1519        ----------
1520        session : VISASession
1521            Unique logical identifier to a session.
1522        space : constants.AddressSpace
1523            Address space from which to move the data.
1524        offset : int
1525            Offset (in bytes) of the address or register from which to read.
1526        length : int
1527             Number of elements to transfer, where the data width of
1528             the elements to transfer is identical to the source data width.
1529        extended : bool, optional
1530            Use 64 bits offset independent of the platform, by default False.
1531
1532        Returns
1533        -------
1534        data : List[int]
1535            Data read from the bus
1536        status_code : StatusCode
1537            Return value of the library call.
1538
1539        """
1540        raise NotImplementedError
1541
1542    def move_in_16(
1543        self,
1544        session: VISASession,
1545        space: constants.AddressSpace,
1546        offset: int,
1547        length: int,
1548        extended: bool = False,
1549    ) -> Tuple[List[int], StatusCode]:
1550        """Moves an 16-bit block of data to local memory.
1551
1552        Corresponds to viMoveIn816 functions of the VISA library.
1553
1554        Parameters
1555        ----------
1556        session : VISASession
1557            Unique logical identifier to a session.
1558        space : constants.AddressSpace
1559            Address space from which to move the data.
1560        offset : int
1561            Offset (in bytes) of the address or register from which to read.
1562        length : int
1563             Number of elements to transfer, where the data width of
1564             the elements to transfer is identical to the source data width.
1565        extended : bool, optional
1566            Use 64 bits offset independent of the platform, by default False.
1567
1568        Returns
1569        -------
1570        data : List[int]
1571            Data read from the bus
1572        status_code : StatusCode
1573            Return value of the library call.
1574
1575        """
1576        raise NotImplementedError
1577
1578    def move_in_32(
1579        self,
1580        session: VISASession,
1581        space: constants.AddressSpace,
1582        offset: int,
1583        length: int,
1584        extended: bool = False,
1585    ) -> Tuple[List]:
1586        """Moves an 32-bit block of data to local memory.
1587
1588        Corresponds to viMoveIn32* functions of the VISA library.
1589
1590        Parameters
1591        ----------
1592        session : VISASession
1593            Unique logical identifier to a session.
1594        space : constants.AddressSpace
1595            Address space from which to move the data.
1596        offset : int
1597            Offset (in bytes) of the address or register from which to read.
1598        length : int
1599             Number of elements to transfer, where the data width of
1600             the elements to transfer is identical to the source data width.
1601        extended : bool, optional
1602            Use 64 bits offset independent of the platform, by default False.
1603
1604        Returns
1605        -------
1606        data : List[int]
1607            Data read from the bus
1608        status_code : StatusCode
1609            Return value of the library call.
1610
1611        """
1612        raise NotImplementedError
1613
1614    def move_in_64(
1615        self,
1616        session: VISASession,
1617        space: constants.AddressSpace,
1618        offset: int,
1619        length: int,
1620        extended: bool = False,
1621    ) -> Tuple[List[int], StatusCode]:
1622        """Moves an 64-bit block of data to local memory.
1623
1624        Corresponds to viMoveIn8* functions of the VISA library.
1625
1626        Parameters
1627        ----------
1628        session : VISASession
1629            Unique logical identifier to a session.
1630        space : constants.AddressSpace
1631            Address space from which to move the data.
1632        offset : int
1633            Offset (in bytes) of the address or register from which to read.
1634        length : int
1635             Number of elements to transfer, where the data width of
1636             the elements to transfer is identical to the source data width.
1637        extended : bool, optional
1638            Use 64 bits offset independent of the platform, by default False.
1639
1640        Returns
1641        -------
1642        data : List[int]
1643            Data read from the bus
1644        status_code : StatusCode
1645            Return value of the library call.
1646
1647        """
1648        raise NotImplementedError
1649
1650    def move_out_8(
1651        self,
1652        session: VISASession,
1653        space: constants.AddressSpace,
1654        offset: int,
1655        length: int,
1656        data: Iterable[int],
1657        extended: bool = False,
1658    ) -> StatusCode:
1659        """Moves an 8-bit block of data from local memory.
1660
1661        Corresponds to viMoveOut8* functions of the VISA library.
1662
1663        Parameters
1664        ----------
1665        session : VISASession
1666            Unique logical identifier to a session.
1667        space : constants.AddressSpace
1668            Address space into which move the data.
1669        offset : int
1670            Offset (in bytes) of the address or register from which to read.
1671        length : int
1672            Number of elements to transfer, where the data width of
1673            the elements to transfer is identical to the source data width.
1674        data : Iterable[int]
1675            Data to write to bus.
1676        extended : bool, optional
1677            Use 64 bits offset independent of the platform, by default False.
1678
1679        Returns
1680        -------
1681        StatusCode
1682            Return value of the library call.
1683
1684        """
1685        raise NotImplementedError
1686
1687    def move_out_16(
1688        self,
1689        session: VISASession,
1690        space: constants.AddressSpace,
1691        offset: int,
1692        length: int,
1693        data: Iterable[int],
1694        extended: bool = False,
1695    ) -> StatusCode:
1696        """Moves an 16-bit block of data from local memory.
1697
1698        Corresponds to viMoveOut16* functions of the VISA library.
1699
1700        Parameters
1701        ----------
1702        session : VISASession
1703            Unique logical identifier to a session.
1704        space : constants.AddressSpace
1705            Address space into which move the data.
1706        offset : int
1707            Offset (in bytes) of the address or register from which to read.
1708        length : int
1709            Number of elements to transfer, where the data width of
1710            the elements to transfer is identical to the source data width.
1711        data : Iterable[int]
1712            Data to write to bus.
1713        extended : bool, optional
1714            Use 64 bits offset independent of the platform, by default False.
1715
1716        Returns
1717        -------
1718        StatusCode
1719            Return value of the library call.
1720
1721        """
1722        raise NotImplementedError
1723
1724    def move_out_32(
1725        self,
1726        session: VISASession,
1727        space: constants.AddressSpace,
1728        offset: int,
1729        length: int,
1730        data: Iterable[int],
1731        extended: bool = False,
1732    ) -> StatusCode:
1733        """Moves an 32-bit block of data from local memory.
1734
1735        Corresponds to viMoveOut32* functions of the VISA library.
1736
1737        Parameters
1738        ----------
1739        session : VISASession
1740            Unique logical identifier to a session.
1741        space : constants.AddressSpace
1742            Address space into which move the data.
1743        offset : int
1744            Offset (in bytes) of the address or register from which to read.
1745        length : int
1746            Number of elements to transfer, where the data width of
1747            the elements to transfer is identical to the source data width.
1748        data : Iterable[int]
1749            Data to write to bus.
1750        extended : bool, optional
1751            Use 64 bits offset independent of the platform, by default False.
1752
1753        Returns
1754        -------
1755        StatusCode
1756            Return value of the library call.
1757
1758
1759        """
1760        raise NotImplementedError
1761
1762    def move_out_64(
1763        self,
1764        session: VISASession,
1765        space: constants.AddressSpace,
1766        offset: int,
1767        length: int,
1768        data: Iterable[int],
1769        extended: bool = False,
1770    ) -> StatusCode:
1771        """Moves an 64-bit block of data from local memory.
1772
1773        Corresponds to viMoveOut64* functions of the VISA library.
1774
1775        Parameters
1776        ----------
1777        session : VISASession
1778            Unique logical identifier to a session.
1779        space : constants.AddressSpace
1780            Address space into which move the data.
1781        offset : int
1782            Offset (in bytes) of the address or register from which to read.
1783        length : int
1784            Number of elements to transfer, where the data width of
1785            the elements to transfer is identical to the source data width.
1786        data : Iterable[int]
1787            Data to write to bus.
1788        extended : bool, optional
1789            Use 64 bits offset independent of the platform, by default False.
1790
1791        Returns
1792        -------
1793        StatusCode
1794            Return value of the library call.
1795
1796        """
1797        raise NotImplementedError
1798
1799    def open(
1800        self,
1801        session: VISARMSession,
1802        resource_name: str,
1803        access_mode: constants.AccessModes = constants.AccessModes.no_lock,
1804        open_timeout: int = constants.VI_TMO_IMMEDIATE,
1805    ) -> Tuple[VISASession, StatusCode]:
1806        """Opens a session to the specified resource.
1807
1808        Corresponds to viOpen function of the VISA library.
1809
1810        Parameters
1811        ----------
1812        session : VISARMSession
1813            Resource Manager session (should always be a session returned from
1814            open_default_resource_manager()).
1815        resource_name : str
1816            Unique symbolic name of a resource.
1817        access_mode : constants.AccessModes, optional
1818            Specifies the mode by which the resource is to be accessed.
1819        open_timeout : int
1820            If the ``access_mode`` parameter requests a lock, then this
1821            parameter specifies the absolute time period (in milliseconds) that
1822            the resource waits to get unlocked before this operation returns an
1823            error.
1824
1825        Returns
1826        -------
1827        VISASession
1828            Unique logical identifier reference to a session
1829        StatusCode
1830            Return value of the library call.
1831
1832        """
1833        raise NotImplementedError
1834
1835    def open_default_resource_manager(self) -> Tuple[VISARMSession, StatusCode]:
1836        """This function returns a session to the Default Resource Manager resource.
1837
1838        Corresponds to viOpenDefaultRM function of the VISA library.
1839
1840        Returns
1841        -------
1842        VISARMSession
1843            Unique logical identifier to a Default Resource Manager session
1844        StatusCode
1845            Return value of the library call.
1846
1847        """
1848        raise NotImplementedError
1849
1850    def out_8(
1851        self,
1852        session: VISASession,
1853        space: constants.AddressSpace,
1854        offset: int,
1855        data: int,
1856        extended: bool = False,
1857    ) -> StatusCode:
1858        """Write an 8-bit value to the specified memory space and offset.
1859
1860        Corresponds to viOut8* functions of the VISA library.
1861
1862        Parameters
1863        ----------
1864        session : VISASession
1865            Unique logical identifier to a session.
1866        space : constants.AddressSpace
1867            Address space into which to write.
1868        offset : int
1869            Offset (in bytes) of the address or register from which to read.
1870        data : int
1871            Data to write to bus.
1872        extended : bool, optional
1873            Use 64 bits offset independent of the platform.
1874
1875        Returns
1876        -------
1877        StatusCode
1878            Return value of the library call.
1879
1880        """
1881        raise NotImplementedError
1882
1883    def out_16(
1884        self,
1885        session: VISASession,
1886        space: constants.AddressSpace,
1887        offset: int,
1888        data: int,
1889        extended: bool = False,
1890    ) -> StatusCode:
1891        """Write a 16-bit value to the specified memory space and offset.
1892
1893        Corresponds to viOut16* functions of the VISA library.
1894
1895        Parameters
1896        ----------
1897        session : VISASession
1898            Unique logical identifier to a session.
1899        space : constants.AddressSpace
1900            Address space into which to write.
1901        offset : int
1902            Offset (in bytes) of the address or register from which to read.
1903        data : int
1904            Data to write to bus.
1905        extended : bool, optional
1906            Use 64 bits offset independent of the platform.
1907
1908        Returns
1909        -------
1910        StatusCode
1911            Return value of the library call.
1912
1913        """
1914        raise NotImplementedError
1915
1916    def out_32(
1917        self,
1918        session: VISASession,
1919        space: constants.AddressSpace,
1920        offset: int,
1921        data: Iterable[int],
1922        extended: bool = False,
1923    ) -> StatusCode:
1924        """Write a 32-bit value to the specified memory space and offset.
1925
1926        Corresponds to viOut32* functions of the VISA library.
1927
1928        Parameters
1929        ----------
1930        session : VISASession
1931            Unique logical identifier to a session.
1932        space : constants.AddressSpace
1933            Address space into which to write.
1934        offset : int
1935            Offset (in bytes) of the address or register from which to read.
1936        data : int
1937            Data to write to bus.
1938        extended : bool, optional
1939            Use 64 bits offset independent of the platform.
1940
1941        Returns
1942        -------
1943        StatusCode
1944            Return value of the library call.
1945
1946        """
1947        raise NotImplementedError
1948
1949    def out_64(
1950        self,
1951        session: VISASession,
1952        space: constants.AddressSpace,
1953        offset: int,
1954        data: Iterable[int],
1955        extended: bool = False,
1956    ) -> StatusCode:
1957        """Write a 64-bit value to the specified memory space and offset.
1958
1959        Corresponds to viOut64* functions of the VISA library.
1960
1961        Parameters
1962        ----------
1963        session : VISASession
1964            Unique logical identifier to a session.
1965        space : constants.AddressSpace
1966            Address space into which to write.
1967        offset : int
1968            Offset (in bytes) of the address or register from which to read.
1969        data : int
1970            Data to write to bus.
1971        extended : bool, optional
1972            Use 64 bits offset independent of the platform.
1973
1974        Returns
1975        -------
1976        StatusCode
1977            Return value of the library call.
1978
1979        """
1980        raise NotImplementedError
1981
1982    def parse_resource(
1983        self, session: VISARMSession, resource_name: str
1984    ) -> Tuple[ResourceInfo, StatusCode]:
1985        """Parse a resource string to get the interface information.
1986
1987        Corresponds to viParseRsrc function of the VISA library.
1988
1989        Parameters
1990        ----------
1991        session : VISARMSession
1992            Resource Manager session (should always be the Default Resource
1993            Manager for VISA returned from open_default_resource_manager()).
1994        resource_name : str
1995             Unique symbolic name of a resource.
1996
1997        Returns
1998        -------
1999        ResourceInfo
2000            Resource information with interface type and board number
2001        StatusCode
2002            Return value of the library call.
2003
2004        """
2005        ri, status = self.parse_resource_extended(session, resource_name)
2006        if status == StatusCode.success:
2007            return (
2008                ResourceInfo(
2009                    ri.interface_type, ri.interface_board_number, None, None, None
2010                ),
2011                StatusCode.success,
2012            )
2013        else:
2014            return ri, status
2015
2016    def parse_resource_extended(
2017        self, session: VISARMSession, resource_name: str
2018    ) -> Tuple[ResourceInfo, StatusCode]:
2019        """Parse a resource string to get extended interface information.
2020
2021        Corresponds to viParseRsrcEx function of the VISA library.
2022
2023        Parameters
2024        ----------
2025        session : VISARMSession
2026            Resource Manager session (should always be the Default Resource
2027            Manager for VISA returned from open_default_resource_manager()).
2028        resource_name : str
2029             Unique symbolic name of a resource.
2030
2031        Returns
2032        -------
2033        ResourceInfo
2034            Resource information with interface type and board number
2035        StatusCode
2036            Return value of the library call.
2037
2038        """
2039        try:
2040            parsed = rname.parse_resource_name(resource_name)
2041        except ValueError:
2042            return (
2043                ResourceInfo(constants.InterfaceType.unknown, 0, None, None, None),
2044                StatusCode.error_invalid_resource_name,
2045            )
2046
2047        board_number: Optional[int]
2048        try:
2049            # We can only get concrete classes which have one of those attributes
2050            board_number = int(
2051                parsed.board  # type: ignore
2052                if hasattr(parsed, "board")
2053                else parsed.interface  # type: ignore
2054            )
2055        # In some cases the board number may not be convertible to an int
2056        # PyVISA-py serial resources on Linux for example
2057        except ValueError:
2058            board_number = None
2059
2060        return (
2061            ResourceInfo(
2062                parsed.interface_type_const,
2063                board_number,
2064                parsed.resource_class,
2065                str(parsed),
2066                None,
2067            ),
2068            StatusCode.success,
2069        )
2070
2071    def peek_8(
2072        self, session: VISASession, address: VISAMemoryAddress
2073    ) -> Tuple[int, StatusCode]:
2074        """Read an 8-bit value from the specified address.
2075
2076        Corresponds to viPeek8 function of the VISA library.
2077
2078        Parameters
2079        ----------
2080        session : VISASession
2081            Unique logical identifier to a session.
2082        address : VISAMemoryAddress
2083            Source address to read the value.
2084
2085        Returns
2086        -------
2087        int
2088            Data read from bus
2089        StatusCode
2090            Return value of the library call.
2091
2092        """
2093        raise NotImplementedError
2094
2095    def peek_16(
2096        self, session: VISASession, address: VISAMemoryAddress
2097    ) -> Tuple[int, StatusCode]:
2098        """Read an 16-bit value from the specified address.
2099
2100        Corresponds to viPeek16 function of the VISA library.
2101
2102        Parameters
2103        ----------
2104        session : VISASession
2105            Unique logical identifier to a session.
2106        address : VISAMemoryAddress
2107            Source address to read the value.
2108
2109        Returns
2110        -------
2111        int
2112            Data read from bus
2113        StatusCode
2114            Return value of the library call.
2115
2116        """
2117        raise NotImplementedError
2118
2119    def peek_32(
2120        self, session: VISASession, address: VISAMemoryAddress
2121    ) -> Tuple[int, StatusCode]:
2122        """Read an 32-bit value from the specified address.
2123
2124        Corresponds to viPeek32 function of the VISA library.
2125
2126        Parameters
2127        ----------
2128        session : VISASession
2129            Unique logical identifier to a session.
2130        address : VISAMemoryAddress
2131            Source address to read the value.
2132
2133        Returns
2134        -------
2135        int
2136            Data read from bus
2137        StatusCode
2138            Return value of the library call.
2139
2140        """
2141        raise NotImplementedError
2142
2143    def peek_64(
2144        self, session: VISASession, address: VISAMemoryAddress
2145    ) -> Tuple[int, StatusCode]:
2146        """Read an 64-bit value from the specified address.
2147
2148        Corresponds to viPeek64 function of the VISA library.
2149
2150        Parameters
2151        ----------
2152        session : VISASession
2153            Unique logical identifier to a session.
2154        address : VISAMemoryAddress
2155            Source address to read the value.
2156
2157        Returns
2158        -------
2159        int
2160            Data read from bus
2161        StatusCode
2162            Return value of the library call.
2163
2164        """
2165        raise NotImplementedError
2166
2167    def poke_8(
2168        self, session: VISASession, address: VISAMemoryAddress, data: int
2169    ) -> StatusCode:
2170        """Write an 8-bit value to the specified address.
2171
2172        Corresponds to viPoke8 function of the VISA library.
2173
2174        Parameters
2175        ----------
2176        session : VISASession
2177            Unique logical identifier to a session.
2178        address : VISAMemoryAddress
2179            Source address to read the value.
2180        data : int
2181            Data to write.
2182
2183        Returns
2184        -------
2185        StatusCode
2186            Return value of the library call.
2187
2188        """
2189        raise NotImplementedError
2190
2191    def poke_16(
2192        self, session: VISASession, address: VISAMemoryAddress, data: int
2193    ) -> StatusCode:
2194        """Write an 16-bit value to the specified address.
2195
2196        Corresponds to viPoke16 function of the VISA library.
2197
2198        Parameters
2199        ----------
2200        session : VISASession
2201            Unique logical identifier to a session.
2202        address : VISAMemoryAddress
2203            Source address to read the value.
2204        data : int
2205            Data to write.
2206
2207        Returns
2208        -------
2209        StatusCode
2210            Return value of the library call.
2211
2212        """
2213        raise NotImplementedError
2214
2215    def poke_32(
2216        self, session: VISASession, address: VISAMemoryAddress, data: int
2217    ) -> StatusCode:
2218        """Write an 32-bit value to the specified address.
2219
2220        Corresponds to viPoke32 function of the VISA library.
2221
2222        Parameters
2223        ----------
2224        session : VISASession
2225            Unique logical identifier to a session.
2226        address : VISAMemoryAddress
2227            Source address to read the value.
2228        data : int
2229            Data to write.
2230
2231        Returns
2232        -------
2233        StatusCode
2234            Return value of the library call.
2235
2236        """
2237        raise NotImplementedError
2238
2239    def poke_64(
2240        self, session: VISASession, address: VISAMemoryAddress, data: int
2241    ) -> StatusCode:
2242        """Write an 64-bit value to the specified address.
2243
2244        Corresponds to viPoke64 function of the VISA library.
2245
2246        Parameters
2247        ----------
2248        session : VISASession
2249            Unique logical identifier to a session.
2250        address : VISAMemoryAddress
2251            Source address to read the value.
2252        data : int
2253            Data to write.
2254
2255        Returns
2256        -------
2257        StatusCode
2258            Return value of the library call.
2259
2260        """
2261        raise NotImplementedError
2262
2263    def read(self, session: VISASession, count: int) -> Tuple[bytes, StatusCode]:
2264        """Reads data from device or interface synchronously.
2265
2266        Corresponds to viRead function of the VISA library.
2267
2268        Parameters
2269        ----------
2270        session : VISASession
2271            Unique logical identifier to a session.
2272        count : int
2273            Number of bytes to be read.
2274
2275        Returns
2276        -------
2277        bytes
2278            Date read
2279        StatusCode
2280            Return value of the library call.
2281
2282        """
2283        raise NotImplementedError
2284
2285    def read_asynchronously(
2286        self, session: VISASession, count: int
2287    ) -> Tuple[SupportsBytes, VISAJobID, StatusCode]:
2288        """Reads data from device or interface asynchronously.
2289
2290        Corresponds to viReadAsync function of the VISA library. Since the
2291        asynchronous operation may complete before the function call return
2292        implementation should make sure that get_buffer_from_id will be able
2293        to return the proper buffer before this method returns.
2294
2295        Parameters
2296        ----------
2297        session : VISASession
2298            Unique logical identifier to a session.
2299        count : int
2300            Number of bytes to be read.
2301
2302        Returns
2303        -------
2304        SupportsBytes
2305            Buffer that will be filled during the asynchronous operation.
2306        VISAJobID
2307            Id of the asynchronous job
2308        StatusCode
2309            Return value of the library call.
2310
2311        """
2312        raise NotImplementedError
2313
2314    def get_buffer_from_id(self, job_id: VISAJobID) -> Optional[SupportsBytes]:
2315        """Retrieve the buffer associated with a job id created in read_asynchronously
2316
2317        Parameters
2318        ----------
2319        job_id : VISAJobID
2320            Id of the job for which to retrieve the buffer.
2321
2322        Returns
2323        -------
2324        Optional[SupportsBytes]
2325            Buffer in which the data are stored or None if the job id is not
2326            associated with any job.
2327
2328        """
2329        raise NotImplementedError
2330
2331    def read_stb(self, session: VISASession) -> Tuple[int, StatusCode]:
2332        """Reads a status byte of the service request.
2333
2334        Corresponds to viReadSTB function of the VISA library.
2335
2336        Parameters
2337        ----------
2338        session : VISASession
2339            Unique logical identifier to a session.
2340
2341        Returns
2342        -------
2343        int
2344            Service request status byte
2345        StatusCode
2346            Return value of the library call.
2347
2348        """
2349        raise NotImplementedError
2350
2351    def read_to_file(
2352        self, session: VISASession, filename: str, count: int
2353    ) -> Tuple[int, StatusCode]:
2354        """Read data synchronously, and store the transferred data in a file.
2355
2356        Corresponds to viReadToFile function of the VISA library.
2357
2358        Parameters
2359        ----------
2360        session : VISASession
2361            Unique logical identifier to a session.
2362        filename : str
2363            Name of file to which data will be written.
2364        count : int
2365            Number of bytes to be read.
2366
2367        Returns
2368        -------
2369        int
2370            Number of bytes actually transferred
2371        StatusCode
2372            Return value of the library call.
2373
2374        """
2375        raise NotImplementedError
2376
2377    def set_attribute(
2378        self,
2379        session: VISASession,
2380        attribute: constants.ResourceAttribute,
2381        attribute_state: Any,
2382    ) -> StatusCode:
2383        """Set the state of an attribute.
2384
2385        Corresponds to viSetAttribute function of the VISA library.
2386
2387        Parameters
2388        ----------
2389        session : VISASession
2390            Unique logical identifier to a session.
2391        attribute : constants.ResourceAttribute
2392            Attribute for which the state is to be modified.
2393        attribute_state : Any
2394            The state of the attribute to be set for the specified object.
2395
2396        Returns
2397        -------
2398        StatusCode
2399            Return value of the library call.
2400
2401        """
2402        raise NotImplementedError
2403
2404    def set_buffer(
2405        self, session: VISASession, mask: constants.BufferType, size: int
2406    ) -> StatusCode:
2407        """Set the size for the formatted I/O and/or low-level I/O communication buffer(s).
2408
2409        Corresponds to viSetBuf function of the VISA library.
2410
2411        Parameters
2412        ----------
2413        session : VISASession
2414            Unique logical identifier to a session.
2415        mask : constants.BufferType
2416            Specifies the type of buffer.
2417        size : int
2418            The size to be set for the specified buffer(s).
2419
2420        Returns
2421        -------
2422        StatusCode
2423            Return value of the library call.
2424
2425        """
2426        raise NotImplementedError
2427
2428    def status_description(
2429        self, session: VISASession, status: StatusCode
2430    ) -> Tuple[str, StatusCode]:
2431        """Return a user-readable description of the status code passed to the operation.
2432
2433        Corresponds to viStatusDesc function of the VISA library.
2434
2435        Parameters
2436        ----------
2437        session : VISASession
2438            Unique logical identifier to a session.
2439        status : StatusCode
2440            Status code to interpret.
2441
2442        Returns
2443        -------
2444        str
2445            User-readable string interpretation of the status code.
2446        StatusCode
2447            Return value of the library call.
2448
2449        """
2450        raise NotImplementedError
2451
2452    def terminate(
2453        self, session: VISASession, degree: None, job_id: VISAJobID
2454    ) -> StatusCode:
2455        """Request a VISA session to terminate normal execution of an operation.
2456
2457        Corresponds to viTerminate function of the VISA library.
2458
2459        Parameters
2460        ----------
2461        session : VISASession
2462            Unique logical identifier to a session.
2463        degree : None
2464            Not used in this version of the VISA specification.
2465        job_id : VISAJobId
2466            Specifies an operation identifier. If a user passes None as the
2467            job_id value to viTerminate(), a VISA implementation should abort
2468            any calls in the current process executing on the specified vi.
2469            Any call that is terminated this way should return VI_ERROR_ABORT.
2470
2471        Returns
2472        -------
2473        StatusCode
2474            Return value of the library call.
2475
2476        """
2477        raise NotImplementedError
2478
2479    def uninstall_handler(
2480        self,
2481        session: VISASession,
2482        event_type: constants.EventType,
2483        handler: VISAHandler,
2484        user_handle: Any = None,
2485    ) -> StatusCode:
2486        """Uninstall handlers for events.
2487
2488        Corresponds to viUninstallHandler function of the VISA library.
2489
2490        Parameters
2491        ----------
2492        session : VISASession
2493            Unique logical identifier to a session.
2494        event_type : constants.EventType
2495            Logical event identifier.
2496        handler : VISAHandler
2497            Handler to be uninstalled by a client application.
2498        user_handle:
2499            A value specified by an application that can be used for
2500            identifying handlers uniquely in a session for an event.
2501            The modified value of the user_handle as returned by install_handler
2502            should be used instead of the original value.
2503
2504        Returns
2505        -------
2506        StatusCode
2507            Return value of the library call.
2508
2509        """
2510        raise NotImplementedError
2511
2512    def unlock(self, session: VISASession) -> StatusCode:
2513        """Relinquish a lock for the specified resource.
2514
2515        Corresponds to viUnlock function of the VISA library.
2516
2517        Parameters
2518        ----------
2519        session : VISASession
2520            Unique logical identifier to a session.
2521
2522        Returns
2523        -------
2524        StatusCode
2525            Return value of the library call.
2526
2527        """
2528        raise NotImplementedError
2529
2530    def unmap_address(self, session: VISASession) -> StatusCode:
2531        """Unmap memory space previously mapped by map_address().
2532
2533        Corresponds to viUnmapAddress function of the VISA library.
2534
2535        Parameters
2536        ----------
2537        session : VISASession
2538            Unique logical identifier to a session.
2539
2540        Returns
2541        -------
2542        StatusCode
2543            Return value of the library call.
2544
2545        """
2546        raise NotImplementedError
2547
2548    def unmap_trigger(
2549        self,
2550        session: VISASession,
2551        trigger_source: constants.InputTriggerLine,
2552        trigger_destination: constants.OutputTriggerLine,
2553    ) -> StatusCode:
2554        """Undo a previous map between a trigger source line and a destination line.
2555
2556        Corresponds to viUnmapTrigger function of the VISA library.
2557
2558        Parameters
2559        ----------
2560        session : VISASession
2561            Unique logical identifier to a session.
2562        trigger_source : constants.InputTriggerLine
2563            Source line used in previous map.
2564        trigger_destination : constants.OutputTriggerLine
2565            Destination line used in previous map.
2566
2567        Returns
2568        -------
2569        StatusCode
2570            Return value of the library call.
2571
2572        """
2573        raise NotImplementedError
2574
2575    def usb_control_in(
2576        self,
2577        session: VISASession,
2578        request_type_bitmap_field: int,
2579        request_id: int,
2580        request_value: int,
2581        index: int,
2582        length: int = 0,
2583    ) -> Tuple[bytes, StatusCode]:
2584        """Perform a USB control pipe transfer from the device.
2585
2586        Corresponds to viUsbControlIn function of the VISA library.
2587
2588        Parameters
2589        ----------
2590        session : VISASession
2591            Unique logical identifier to a session.
2592        request_type_bitmap_field : int
2593            bmRequestType parameter of the setup stage of a USB control transfer.
2594        request_id : int
2595            bRequest parameter of the setup stage of a USB control transfer.
2596        request_value : int
2597            wValue parameter of the setup stage of a USB control transfer.
2598        index : int
2599            wIndex parameter of the setup stage of a USB control transfer.
2600            This is usually the index of the interface or endpoint.
2601        length : int, optional
2602            wLength parameter of the setup stage of a USB control transfer.
2603            This value also specifies the size of the data buffer to receive
2604            the data from the optional data stage of the control transfer.
2605
2606        Returns
2607        -------
2608        bytes
2609            The data buffer that receives the data from the optional data stage
2610            of the control transfer
2611        StatusCode
2612            Return value of the library call.
2613
2614        """
2615        raise NotImplementedError
2616
2617    def usb_control_out(
2618        self,
2619        session: VISASession,
2620        request_type_bitmap_field: int,
2621        request_id: int,
2622        request_value: int,
2623        index: int,
2624        data: bytes = b"",
2625    ) -> StatusCode:
2626        """Perform a USB control pipe transfer to the device.
2627
2628        Corresponds to viUsbControlOut function of the VISA library.
2629
2630        Parameters
2631        ----------
2632        session : VISASession
2633            Unique logical identifier to a session.
2634        request_type_bitmap_field : int
2635            bmRequestType parameter of the setup stage of a USB control transfer.
2636        request_id : int
2637            bRequest parameter of the setup stage of a USB control transfer.
2638        request_value : int
2639            wValue parameter of the setup stage of a USB control transfer.
2640        index : int
2641            wIndex parameter of the setup stage of a USB control transfer.
2642            This is usually the index of the interface or endpoint.
2643        data : bytes, optional
2644            The data buffer that sends the data in the optional data stage of
2645            the control transfer.
2646
2647        Returns
2648        -------
2649        StatusCode
2650            Return value of the library call.
2651
2652        """
2653        raise NotImplementedError
2654
2655    def vxi_command_query(
2656        self, session: VISASession, mode: constants.VXICommands, command: int
2657    ) -> Tuple[int, StatusCode]:
2658        """Send the device a miscellaneous command or query and/or retrieves the response to a previous query.
2659
2660        Corresponds to viVxiCommandQuery function of the VISA library.
2661
2662        Parameters
2663        ----------
2664        session : VISASession
2665            Unique logical identifier to a session.
2666        mode : constants.VXICommands
2667            Specifies whether to issue a command and/or retrieve a response.
2668        command : int
2669            The miscellaneous command to send.
2670
2671        Returns
2672        -------
2673        int
2674            The response retrieved from the device
2675        StatusCode
2676            Return value of the library call.
2677
2678        """
2679        raise NotImplementedError
2680
2681    def wait_on_event(
2682        self, session: VISASession, in_event_type: constants.EventType, timeout: int
2683    ) -> Tuple[constants.EventType, VISAEventContext, StatusCode]:
2684        """Wait for an occurrence of the specified event for a given session.
2685
2686        Corresponds to viWaitOnEvent function of the VISA library.
2687
2688        Parameters
2689        ----------
2690        session : VISASession
2691            Unique logical identifier to a session.
2692        in_event_type : constants.EventType
2693            Logical identifier of the event(s) to wait for.
2694        timeout : int
2695            Absolute time period in time units that the resource shall wait for
2696            a specified event to occur before returning the time elapsed error.
2697            The time unit is in milliseconds.
2698
2699        Returns
2700        -------
2701        constants.EventType
2702            Logical identifier of the event actually received
2703        VISAEventContext
2704            A handle specifying the unique occurrence of an event
2705        StatusCode
2706            Return value of the library call.
2707
2708        """
2709        raise NotImplementedError
2710
2711    def write(self, session: VISASession, data: bytes) -> Tuple[int, StatusCode]:
2712        """Write data to device or interface synchronously.
2713
2714        Corresponds to viWrite function of the VISA library.
2715
2716        Parameters
2717        ----------
2718        session : VISASession
2719            Unique logical identifier to a session.
2720        data : bytes
2721            Data to be written.
2722
2723        Returns
2724        -------
2725        int
2726            Number of bytes actually transferred
2727        StatusCode
2728            Return value of the library call.
2729
2730        """
2731        raise NotImplementedError
2732
2733    def write_asynchronously(
2734        self, session: VISASession, data: bytes
2735    ) -> Tuple[VISAJobID, StatusCode]:
2736        """Write data to device or interface asynchronously.
2737
2738        Corresponds to viWriteAsync function of the VISA library.
2739
2740        Parameters
2741        ----------
2742        session : VISASession
2743            Unique logical identifier to a session.
2744        data : bytes
2745            Data to be written.
2746
2747        Returns
2748        -------
2749        VISAJobID
2750            Job ID of this asynchronous write operation
2751        StatusCode
2752            Return value of the library call.
2753
2754        """
2755        raise NotImplementedError
2756
2757    def write_from_file(
2758        self, session: VISASession, filename: str, count: int
2759    ) -> Tuple[int, StatusCode]:
2760        """Take data from a file and write it out synchronously.
2761
2762        Corresponds to viWriteFromFile function of the VISA library.
2763
2764        Parameters
2765        ----------
2766        session : VISASession
2767            Unique logical identifier to a session.
2768        filename : str
2769            Name of file from which data will be read.
2770        count : int
2771            Number of bytes to be written.
2772
2773        Returns
2774        -------
2775        int
2776            Number of bytes actually transferred
2777        StatusCode
2778            Return value of the library call.
2779
2780        """
2781        raise NotImplementedError
2782
2783
2784def list_backends() -> List[str]:
2785    """Return installed backends.
2786
2787    Backends are installed python packages named pyvisa_<something> where <something>
2788    is the name of the backend.
2789
2790    """
2791    return ["ivi"] + [
2792        name[7:]
2793        for (loader, name, ispkg) in pkgutil.iter_modules()
2794        if (name.startswith("pyvisa_") or name.startswith("pyvisa-"))
2795        and not name.endswith("-script")
2796    ]
2797
2798
2799#: Maps backend name to VisaLibraryBase derived class
2800_WRAPPERS: Dict[str, Type[VisaLibraryBase]] = {}
2801
2802
2803class PyVISAModule(ModuleType):
2804
2805    WRAPPER_CLASS: Type[VisaLibraryBase]
2806
2807
2808def get_wrapper_class(backend_name: str) -> Type[VisaLibraryBase]:
2809    """Return the WRAPPER_CLASS for a given backend.
2810
2811    backend_name == 'ni' is used for backwards compatibility
2812    and will be removed in 1.12.
2813
2814    """
2815    try:
2816        return _WRAPPERS[backend_name]
2817    except KeyError:
2818        if backend_name == "ivi" or backend_name == "ni":
2819            from .ctwrapper import IVIVisaLibrary
2820
2821            _WRAPPERS["ivi"] = IVIVisaLibrary
2822            if backend_name == "ni":
2823                warnings.warn(
2824                    "@ni backend name is deprecated and will be "
2825                    "removed in 1.12. Use @ivi instead. "
2826                    "Check the documentation for details",
2827                    FutureWarning,
2828                )
2829            return IVIVisaLibrary
2830
2831    pkg: PyVISAModule
2832    try:
2833        pkg = cast(PyVISAModule, import_module("pyvisa_" + backend_name))
2834        _WRAPPERS[backend_name] = cls = pkg.WRAPPER_CLASS
2835        return cls
2836    except ImportError:
2837        try:
2838            pkg = cast(PyVISAModule, import_module("pyvisa-" + backend_name))
2839            _WRAPPERS[backend_name] = cls = pkg.WRAPPER_CLASS
2840            warnings.warn(
2841                "Backends packages should use an _ rather than a - ."
2842                "Project can/should keep using a - (like pytest plugins)."
2843                "Support for backends with - will be removed in 1.12",
2844                FutureWarning,
2845            )
2846            return cls
2847        except ImportError:
2848            raise ValueError(
2849                "Wrapper not found: No package named pyvisa_%s" % backend_name
2850            )
2851
2852
2853def _get_default_wrapper() -> str:
2854    """Return an available default VISA wrapper as a string ('ivi' or 'py').
2855
2856    Use IVI if the binary is found, else try to use pyvisa-py.
2857
2858    'ni' VISA wrapper is NOT used since version > 1.10.0
2859    and will be removed in 1.12
2860
2861    Raises
2862    ------
2863    ValueError
2864        If no backend can be found
2865
2866    """
2867
2868    from .ctwrapper import IVIVisaLibrary
2869
2870    ivi_binary_found = bool(IVIVisaLibrary.get_library_paths())
2871    if ivi_binary_found:
2872        logger.debug("The IVI implementation available")
2873        return "ivi"
2874    else:
2875        logger.debug("Did not find IVI binary")
2876
2877    try:
2878        get_wrapper_class("py")  # check for pyvisa-py availability
2879        logger.debug("pyvisa-py is available.")
2880        return "py"
2881    except ValueError:
2882        logger.debug("Did not find pyvisa-py package")
2883    raise ValueError(
2884        "Could not locate a VISA implementation. Install either the IVI binary or pyvisa-py."
2885    )
2886
2887
2888def open_visa_library(specification: str = "") -> VisaLibraryBase:
2889    """Helper function to create a VISA library wrapper.
2890
2891    In general, you should not use the function directly. The VISA library
2892    wrapper will be created automatically when you create a ResourceManager object.
2893
2894    Parameters
2895    ----------
2896    specification : str, optional
2897        The specification has 2 parts separated by a '@', ex: path/visa.dll@ivi
2898        The second part is the backend name (ivi, py, ...) while the first part
2899        will be passed to the library object. In the case of the ivi backend it
2900        should the path to the VISA library.
2901        Either part can be omitted. If the second part is omitted, the system
2902        will fall back to the ivi backend if available or the pyvisa-py backend
2903        if the first part is also omitted.
2904
2905    """
2906
2907    if not specification:
2908        logger.debug("No visa library specified, trying to find alternatives.")
2909        try:
2910            specification = os.environ["PYVISA_LIBRARY"]
2911        except KeyError:
2912            logger.debug("Environment variable PYVISA_LIBRARY is unset.")
2913
2914    wrapper: Optional[str]
2915    try:
2916        argument, wrapper = specification.split("@")
2917    except ValueError:
2918        argument = specification
2919        wrapper = None  # Flag that we need a fallback, but avoid nested exceptions
2920    if wrapper is None:
2921        if argument:  # some filename given
2922            wrapper = "ivi"
2923        else:
2924            wrapper = _get_default_wrapper()
2925
2926    cls = get_wrapper_class(wrapper)
2927
2928    try:
2929        return cls(argument)
2930    except Exception as e:
2931        logger.debug("Could not open VISA wrapper %s: %s\n%s", cls, str(argument), e)
2932        raise
2933
2934
2935class ResourceManager(object):
2936    """VISA Resource Manager. """
2937
2938    #: Maps (Interface Type, Resource Class) to Python class encapsulating that resource.
2939    _resource_classes: ClassVar[
2940        Dict[Tuple[constants.InterfaceType, str], Type["Resource"]]
2941    ] = dict()
2942
2943    #: Session handler for the resource manager.
2944    _session: Optional[VISARMSession] = None
2945
2946    #: Reference to the VISA library used by the ResourceManager
2947    visalib: VisaLibraryBase
2948
2949    #: Resources created by this manager to allow closing them when the manager is closed
2950    _created_resources: WeakSet
2951
2952    #: Handler for atexit using a weakref to close
2953    _atexit_handler: Callable
2954
2955    @classmethod
2956    def register_resource_class(
2957        cls,
2958        interface_type: constants.InterfaceType,
2959        resource_class: str,
2960        python_class: Type["Resource"],
2961    ) -> None:
2962        """Register a class for a specific interface type, resource class pair.
2963
2964        Parameters
2965        ----------
2966        interface_type : constants.InterfaceTyp
2967            Interface type for which to use the provided class.
2968        resource_class : str
2969            Resource class (INSTR, INTFC, ...)  for which to use teh povided class.
2970        python_class : Type[Resource]
2971            Subclass of ``Resource`` to use when opening a resource matching the
2972            specified interface type and resource class.
2973
2974        """
2975        if (interface_type, resource_class) in cls._resource_classes:
2976            logger.warning(
2977                "%s is already registered in the ResourceManager. "
2978                "Overwriting with %s" % ((interface_type, resource_class), python_class)
2979            )
2980
2981        # If the class already has this attribute, it means that a parent class
2982        # was registered first. We need to copy the current set and extend it.
2983        attrs = copy.copy(getattr(python_class, "visa_attributes_classes", set()))
2984
2985        for attr in chain(
2986            attributes.AttributesPerResource[(interface_type, resource_class)],
2987            attributes.AttributesPerResource[attributes.AllSessionTypes],
2988        ):
2989            attrs.add(attr)
2990            # Error on non-properly set descriptor (this ensures that we are
2991            # consistent)
2992            if attr.py_name != "" and not hasattr(python_class, attr.py_name):
2993                raise TypeError(
2994                    "%s was expected to have a visa attribute %s"
2995                    % (python_class, attr.py_name)
2996                )
2997
2998        setattr(python_class, "visa_attributes_classes", attrs)
2999
3000        cls._resource_classes[(interface_type, resource_class)] = python_class
3001
3002    def __new__(
3003        cls: Type["ResourceManager"], visa_library: Union[str, VisaLibraryBase] = ""
3004    ) -> "ResourceManager":
3005        """Create a new resource manager tied to the specified VISA library.
3006
3007        Parameters
3008        ----------
3009        visa_library : Union[str, VisaLibraryBase]
3010            Either a fully initialized VisaLibraryBase subclass instance or
3011            a str specification (see open_visa_library for the format).
3012
3013        """
3014        if not isinstance(visa_library, VisaLibraryBase):
3015            visa_library = open_visa_library(visa_library)
3016
3017        if visa_library.resource_manager is not None:
3018            obj = visa_library.resource_manager
3019            logger.debug("Reusing ResourceManager with session %s", obj.session)
3020            return obj
3021
3022        obj = super(ResourceManager, cls).__new__(cls)
3023
3024        obj.session, err = visa_library.open_default_resource_manager()
3025
3026        obj.visalib = visa_library
3027        obj.visalib.resource_manager = obj
3028        obj._created_resources = WeakSet()
3029
3030        # Register an atexit handler to ensure the Resource Manager is properly
3031        # closed.
3032        close_ref = WeakMethod(obj.close)  # type: ignore
3033
3034        def call_close():
3035            meth = close_ref()
3036            if meth:
3037                meth()
3038
3039        atexit.register(call_close)
3040        obj._atexit_handler = call_close  # type: ignore
3041
3042        logger.debug("Created ResourceManager with session %s", obj.session)
3043        return obj
3044
3045    @property
3046    def session(self) -> VISARMSession:
3047        """Resource Manager session handle.
3048
3049        Raises
3050        ------
3051        errors.InvalidSession
3052            Raised if the session is closed.
3053
3054        """
3055        if self._session is None:
3056            raise errors.InvalidSession()
3057        return self._session
3058
3059    @session.setter
3060    def session(self, value: Optional[VISARMSession]) -> None:
3061        self._session = value
3062
3063    def __str__(self) -> str:
3064        return "Resource Manager of %s" % self.visalib
3065
3066    def __repr__(self) -> str:
3067        return "<ResourceManager(%r)>" % self.visalib
3068
3069    def __del__(self) -> None:
3070        if self._session is not None:
3071            self.close()
3072
3073    def ignore_warning(self, *warnings_constants: StatusCode) -> ContextManager:
3074        """Ignoring warnings context manager for the current resource.
3075
3076        Parameters
3077        ----------
3078        warnings_constants : StatusCode
3079            Constants identifying the warnings to ignore.
3080
3081        """
3082        return self.visalib.ignore_warning(self.session, *warnings_constants)
3083
3084    @property
3085    def last_status(self) -> StatusCode:
3086        """Last status code returned for an operation with this Resource Manager."""
3087        return self.visalib.get_last_status_in_session(self.session)
3088
3089    def close(self) -> None:
3090        """Close the resource manager session."""
3091        atexit.unregister(self._atexit_handler)
3092        try:
3093            logger.debug("Closing ResourceManager (session: %s)", self.session)
3094            # Cleanly close all resources when closing the manager.
3095            for resource in self._created_resources:
3096                resource.close()
3097            self.visalib.close(self.session)
3098            # mypy don't get that we can set a value we cannot get
3099            self.session = None  # type: ignore
3100            self.visalib.resource_manager = None
3101        except errors.InvalidSession:
3102            pass
3103
3104    def list_resources(self, query: str = "?*::INSTR") -> Tuple[str, ...]:
3105        r"""Return a tuple of all connected devices matching query.
3106
3107        Notes
3108        -----
3109        The query uses the VISA Resource Regular Expression syntax - which is
3110        not the same as the Python regular expression syntax. (see below)
3111
3112        The VISA Resource Regular Expression syntax is defined in the VISA
3113        Library specification:
3114        http://www.ivifoundation.org/docs/vpp43.pdf
3115
3116        Symbol      Meaning
3117        ----------  ----------
3118
3119        ?           Matches any one character.
3120
3121        \           Makes the character that follows it an ordinary character
3122                    instead of special character. For example, when a question
3123                    mark follows a backslash (\?), it matches the ? character
3124                    instead of any one character.
3125
3126        [list]      Matches any one character from the enclosed list. You can
3127                    use a hyphen to match a range of characters.
3128
3129        [^list]     Matches any character not in the enclosed list. You can use
3130                    a hyphen to match a range of characters.
3131
3132        *           Matches 0 or more occurrences of the preceding character or
3133                    expression.
3134
3135        +           Matches 1 or more occurrences of the preceding character or
3136                    expression.
3137
3138        Exp|exp     Matches either the preceding or following expression. The or
3139                    operator | matches the entire expression that precedes or
3140                    follows it and not just the character that precedes or follows
3141                    it. For example, VXI|GPIB means (VXI)|(GPIB), not VX(I|G)PIB.
3142
3143        (exp)       Grouping characters or expressions.
3144
3145        Thus the default query, '?*::INSTR', matches any sequences of characters
3146        ending ending with '::INSTR'.
3147
3148        On some platforms, devices that are already open are not returned.
3149
3150        """
3151
3152        return self.visalib.list_resources(self.session, query)
3153
3154    def list_resources_info(self, query: str = "?*::INSTR") -> Dict[str, ResourceInfo]:
3155        """Get extended information about all connected devices matching query.
3156
3157        For details of the VISA Resource Regular Expression syntax used in query,
3158        refer to list_resources().
3159
3160        Returns
3161        -------
3162        Dict[str, ResourceInfo]
3163            Mapping of resource name to ResourceInfo
3164
3165        """
3166
3167        return dict(
3168            (resource, self.resource_info(resource))
3169            for resource in self.list_resources(query)
3170        )
3171
3172    def list_opened_resources(self) -> List["Resource"]:
3173        """Return a list of all the opened resources."""
3174        opened = []
3175        for resource in self._created_resources:
3176            try:
3177                resource.session
3178            except errors.InvalidSession:
3179                pass
3180            else:
3181                opened.append(resource)
3182        return opened
3183
3184    def resource_info(self, resource_name: str, extended: bool = True) -> ResourceInfo:
3185        """Get the (extended) information of a particular resource.
3186
3187        Parameters
3188        ----------
3189        resource_name : str
3190            Unique symbolic name of a resource.
3191        extended : bool, optional
3192            Also get extended information (ie. resource_class, resource_name, alias)
3193
3194        """
3195
3196        if extended:
3197            ret, err = self.visalib.parse_resource_extended(self.session, resource_name)
3198        else:
3199            ret, err = self.visalib.parse_resource(self.session, resource_name)
3200
3201        return ret
3202
3203    def open_bare_resource(
3204        self,
3205        resource_name: str,
3206        access_mode: constants.AccessModes = constants.AccessModes.no_lock,
3207        open_timeout: int = constants.VI_TMO_IMMEDIATE,
3208    ) -> Tuple[VISASession, StatusCode]:
3209        """Open the specified resource without wrapping into a class.
3210
3211        Parameters
3212        ----------
3213        resource_name : str
3214            Name or alias of the resource to open.
3215        access_mode : constants.AccessModes, optional
3216            Specifies the mode by which the resource is to be accessed,
3217            by default constants.AccessModes.no_lock
3218        open_timeout : int, optional
3219            If the ``access_mode`` parameter requests a lock, then this
3220            parameter specifies the absolute time period (in milliseconds) that
3221            the resource waits to get unlocked before this operation returns an
3222            error, by default constants.VI_TMO_IMMEDIATE.
3223
3224        Returns
3225        -------
3226        VISASession
3227            Unique logical identifier reference to a session.
3228        StatusCode
3229            Return value of the library call.
3230
3231        """
3232        return self.visalib.open(self.session, resource_name, access_mode, open_timeout)
3233
3234    def open_resource(
3235        self,
3236        resource_name: str,
3237        access_mode: constants.AccessModes = constants.AccessModes.no_lock,
3238        open_timeout: int = constants.VI_TMO_IMMEDIATE,
3239        resource_pyclass: Optional[Type["Resource"]] = None,
3240        **kwargs: Any,
3241    ) -> "Resource":
3242        """Return an instrument for the resource name.
3243
3244        Parameters
3245        ----------
3246        resource_name : str
3247            Name or alias of the resource to open.
3248        access_mode : constants.AccessModes, optional
3249            Specifies the mode by which the resource is to be accessed,
3250            by default constants.AccessModes.no_lock
3251        open_timeout : int, optional
3252            If the ``access_mode`` parameter requests a lock, then this
3253            parameter specifies the absolute time period (in milliseconds) that
3254            the resource waits to get unlocked before this operation returns an
3255            error, by default constants.VI_TMO_IMMEDIATE.
3256        resource_pyclass : Optional[Type[Resource]], optional
3257            Resource Python class to use to instantiate the Resource.
3258            Defaults to None: select based on the resource name.
3259        kwargs : Any
3260            Keyword arguments to be used to change instrument attributes
3261            after construction.
3262
3263        Returns
3264        -------
3265        Resource
3266            Subclass of Resource matching the resource.
3267
3268        """
3269
3270        if resource_pyclass is None:
3271            info = self.resource_info(resource_name, extended=True)
3272
3273            try:
3274                # When using querying extended resource info the resource_class is not
3275                # None
3276                resource_pyclass = self._resource_classes[
3277                    (info.interface_type, info.resource_class)  # type: ignore
3278                ]
3279            except KeyError:
3280                resource_pyclass = self._resource_classes[
3281                    (constants.InterfaceType.unknown, "")
3282                ]
3283                logger.warning(
3284                    "There is no class defined for %r. Using Resource",
3285                    (info.interface_type, info.resource_class),
3286                )
3287
3288        res = resource_pyclass(self, resource_name)
3289        for key in kwargs.keys():
3290            try:
3291                getattr(res, key)
3292                present = True
3293            except AttributeError:
3294                present = False
3295            except errors.InvalidSession:
3296                present = True
3297
3298            if not present:
3299                raise ValueError(
3300                    "%r is not a valid attribute for type %s"
3301                    % (key, res.__class__.__name__)
3302                )
3303
3304        res.open(access_mode, open_timeout)
3305
3306        for key, value in kwargs.items():
3307            setattr(res, key, value)
3308
3309        self._created_resources.add(res)
3310
3311        return res
3312
3313    def get_instrument(
3314        self,
3315        resource_name: str,
3316        access_mode: constants.AccessModes = constants.AccessModes.no_lock,
3317        open_timeout: int = constants.VI_TMO_IMMEDIATE,
3318        resource_pyclass: Type["Resource"] = None,
3319        **kwargs: Any,
3320    ) -> "Resource":
3321        """Return an instrument for the resource name.
3322
3323        .. warning::
3324            get_instrument is deprecated and will be removed in 1.12,
3325            use open_resource instead."
3326
3327        Parameters
3328        ----------
3329        resource_name : str
3330            Name or alias of the resource to open.
3331        access_mode : constants.AccessModes, optional
3332            Specifies the mode by which the resource is to be accessed,
3333            by default constants.AccessModes.no_lock
3334        open_timeout : int, optional
3335            If the ``access_mode`` parameter requests a lock, then this
3336            parameter specifies the absolute time period (in milliseconds) that
3337            the resource waits to get unlocked before this operation returns an
3338            error, by default constants.VI_TMO_IMMEDIATE.
3339        resource_pyclass : Optional[Type[Resource]], optional
3340            Resource Python class to use to instantiate the Resource.
3341            Defaults to None: select based on the resource name.
3342        kwargs : Any
3343            Keyword arguments to be used to change instrument attributes
3344            after construction.
3345
3346        Returns
3347        -------
3348        Resource
3349            Subclass of Resource matching the resource.
3350
3351        """
3352        warnings.warn(
3353            "get_instrument is deprecated and will be removed in "
3354            "1.12, use open_resource instead.",
3355            FutureWarning,
3356        )
3357        return self.open_resource(
3358            resource_name, access_mode, open_timeout, resource_pyclass, **kwargs
3359        )
3360