1# -*- coding: utf-8 -*-
2"""Exceptions hierarchy and textual explanations of VISA completion and error codes.
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 warnings
11from typing import Any, Tuple
12
13from . import typing, util
14from .constants import (
15    VI_ERROR_ABORT,
16    VI_ERROR_ALLOC,
17    VI_ERROR_ASRL_FRAMING,
18    VI_ERROR_ASRL_OVERRUN,
19    VI_ERROR_ASRL_PARITY,
20    VI_ERROR_ATTR_READONLY,
21    VI_ERROR_BERR,
22    VI_ERROR_CLOSING_FAILED,
23    VI_ERROR_CONN_LOST,
24    VI_ERROR_FILE_ACCESS,
25    VI_ERROR_FILE_IO,
26    VI_ERROR_HNDLR_NINSTALLED,
27    VI_ERROR_IN_PROGRESS,
28    VI_ERROR_INP_PROT_VIOL,
29    VI_ERROR_INTF_NUM_NCONFIG,
30    VI_ERROR_INTR_PENDING,
31    VI_ERROR_INV_ACC_MODE,
32    VI_ERROR_INV_ACCESS_KEY,
33    VI_ERROR_INV_CONTEXT,
34    VI_ERROR_INV_DEGREE,
35    VI_ERROR_INV_EVENT,
36    VI_ERROR_INV_EXPR,
37    VI_ERROR_INV_FMT,
38    VI_ERROR_INV_HNDLR_REF,
39    VI_ERROR_INV_JOB_ID,
40    VI_ERROR_INV_LENGTH,
41    VI_ERROR_INV_LINE,
42    VI_ERROR_INV_LOCK_TYPE,
43    VI_ERROR_INV_MASK,
44    VI_ERROR_INV_MECH,
45    VI_ERROR_INV_MODE,
46    VI_ERROR_INV_OBJECT,
47    VI_ERROR_INV_OFFSET,
48    VI_ERROR_INV_PARAMETER,
49    VI_ERROR_INV_PROT,
50    VI_ERROR_INV_RSRC_NAME,
51    VI_ERROR_INV_SETUP,
52    VI_ERROR_INV_SIZE,
53    VI_ERROR_INV_SPACE,
54    VI_ERROR_INV_WIDTH,
55    VI_ERROR_IO,
56    VI_ERROR_LIBRARY_NFOUND,
57    VI_ERROR_LINE_IN_USE,
58    VI_ERROR_MACHINE_NAVAIL,
59    VI_ERROR_MEM_NSHARED,
60    VI_ERROR_NCIC,
61    VI_ERROR_NENABLED,
62    VI_ERROR_NIMPL_OPER,
63    VI_ERROR_NLISTENERS,
64    VI_ERROR_NPERMISSION,
65    VI_ERROR_NSUP_ALIGN_OFFSET,
66    VI_ERROR_NSUP_ATTR,
67    VI_ERROR_NSUP_ATTR_STATE,
68    VI_ERROR_NSUP_FMT,
69    VI_ERROR_NSUP_INTR,
70    VI_ERROR_NSUP_LINE,
71    VI_ERROR_NSUP_MECH,
72    VI_ERROR_NSUP_MODE,
73    VI_ERROR_NSUP_OFFSET,
74    VI_ERROR_NSUP_OPER,
75    VI_ERROR_NSUP_VAR_WIDTH,
76    VI_ERROR_NSUP_WIDTH,
77    VI_ERROR_NSYS_CNTLR,
78    VI_ERROR_OUTP_PROT_VIOL,
79    VI_ERROR_QUEUE_ERROR,
80    VI_ERROR_QUEUE_OVERFLOW,
81    VI_ERROR_RAW_RD_PROT_VIOL,
82    VI_ERROR_RAW_WR_PROT_VIOL,
83    VI_ERROR_RESP_PENDING,
84    VI_ERROR_RSRC_BUSY,
85    VI_ERROR_RSRC_LOCKED,
86    VI_ERROR_RSRC_NFOUND,
87    VI_ERROR_SESN_NLOCKED,
88    VI_ERROR_SRQ_NOCCURRED,
89    VI_ERROR_SYSTEM_ERROR,
90    VI_ERROR_TMO,
91    VI_ERROR_TRIG_NMAPPED,
92    VI_ERROR_USER_BUF,
93    VI_ERROR_WINDOW_MAPPED,
94    VI_ERROR_WINDOW_NMAPPED,
95    VI_SUCCESS,
96    VI_SUCCESS_DEV_NPRESENT,
97    VI_SUCCESS_EVENT_DIS,
98    VI_SUCCESS_EVENT_EN,
99    VI_SUCCESS_MAX_CNT,
100    VI_SUCCESS_NCHAIN,
101    VI_SUCCESS_NESTED_EXCLUSIVE,
102    VI_SUCCESS_NESTED_SHARED,
103    VI_SUCCESS_QUEUE_EMPTY,
104    VI_SUCCESS_QUEUE_NEMPTY,
105    VI_SUCCESS_SYNC,
106    VI_SUCCESS_TERM_CHAR,
107    VI_SUCCESS_TRIG_MAPPED,
108    VI_WARN_CONFIG_NLOADED,
109    VI_WARN_EXT_FUNC_NIMPL,
110    VI_WARN_NSUP_ATTR_STATE,
111    VI_WARN_NSUP_BUF,
112    VI_WARN_NULL_OBJECT,
113    VI_WARN_QUEUE_OVERFLOW,
114    VI_WARN_UNKNOWN_STATUS,
115    EventType,
116    StatusCode,
117)
118
119completion_and_error_messages = {
120    VI_SUCCESS: ("VI_SUCCESS", "Operation completed successfully."),
121    VI_SUCCESS_EVENT_EN: (
122        "VI_SUCCESS_EVENT_EN",
123        "Specified event is already enabled for at "
124        "least one of the specified mechanisms.",
125    ),
126    VI_SUCCESS_EVENT_DIS: (
127        "VI_SUCCESS_EVENT_DIS",
128        "Specified event is already disabled for "
129        "at least one of the specified mechanisms.",
130    ),
131    VI_SUCCESS_QUEUE_EMPTY: (
132        "VI_SUCCESS_QUEUE_EMPTY",
133        "Operation completed successfully, but " "queue was already empty.",
134    ),
135    VI_SUCCESS_TERM_CHAR: (
136        "VI_SUCCESS_TERM_CHAR",
137        "The specified termination character was " "read.",
138    ),
139    VI_SUCCESS_MAX_CNT: (
140        "VI_SUCCESS_MAX_CNT",
141        "The number of bytes transferred is equal "
142        "to the requested input count. More data "
143        "may be available.",
144    ),
145    VI_SUCCESS_DEV_NPRESENT: (
146        "VI_SUCCESS_DEV_NPRESENT",
147        "Session opened successfully, but the "
148        "device at the specified address is not "
149        "responding.",
150    ),
151    VI_SUCCESS_TRIG_MAPPED: (
152        "VI_SUCCESS_TRIG_MAPPED",
153        "The path from trigSrc to trigDest is " "already mapped.",
154    ),
155    VI_SUCCESS_QUEUE_NEMPTY: (
156        "VI_SUCCESS_QUEUE_NEMPTY",
157        "Wait terminated successfully on receipt "
158        "of an event notification. There is at "
159        "least one more event object of the "
160        "requested type(s) available for this "
161        "session.",
162    ),
163    VI_SUCCESS_NCHAIN: (
164        "VI_SUCCESS_NCHAIN",
165        "Event handled successfully. Do not invoke "
166        "any other handlers on this session for "
167        "this event.",
168    ),
169    VI_SUCCESS_NESTED_SHARED: (
170        "VI_SUCCESS_NESTED_SHARED",
171        "Operation completed successfully, and "
172        "this session has nested shared locks.",
173    ),
174    VI_SUCCESS_NESTED_EXCLUSIVE: (
175        "VI_SUCCESS_NESTED_EXCLUSIVE",
176        "Operation completed successfully, and "
177        "this session has nested exclusive locks.",
178    ),
179    VI_SUCCESS_SYNC: (
180        "VI_SUCCESS_SYNC",
181        "Operation completed successfully, but the "
182        "operation was actually synchronous rather "
183        "than asynchronous.",
184    ),
185    VI_WARN_QUEUE_OVERFLOW: (
186        "VI_WARN_QUEUE_OVERFLOW",
187        "VISA received more event information of "
188        "the specified type than the configured "
189        "queue size could hold.",
190    ),
191    VI_WARN_CONFIG_NLOADED: (
192        "VI_WARN_CONFIG_NLOADED",
193        "The specified configuration either does "
194        "not exist or could not be loaded. "
195        "VISA-specified defaults will be used.",
196    ),
197    VI_WARN_NULL_OBJECT: (
198        "VI_WARN_NULL_OBJECT",
199        "The specified object reference is " "uninitialized.",
200    ),
201    VI_WARN_NSUP_ATTR_STATE: (
202        "VI_WARN_NSUP_ATTR_STATE",
203        "Although the specified state of the "
204        "attribute is valid, it is not supported "
205        "by this implementation.",
206    ),
207    VI_WARN_UNKNOWN_STATUS: (
208        "VI_WARN_UNKNOWN_STATUS",
209        "The status code passed to the operation " "could not be interpreted.",
210    ),
211    VI_WARN_NSUP_BUF: (
212        "VI_WARN_NSUP_BUF",
213        "The specified I/O buffer type is not " "supported.",
214    ),
215    VI_WARN_EXT_FUNC_NIMPL: (
216        "VI_WARN_EXT_FUNC_NIMPL",
217        "The operation succeeded, but a lower "
218        "level driver did not implement the "
219        "extended functionality.",
220    ),
221    VI_ERROR_SYSTEM_ERROR: (
222        "VI_ERROR_SYSTEM_ERROR",
223        "Unknown system error (miscellaneous " "error).",
224    ),
225    VI_ERROR_INV_OBJECT: (
226        "VI_ERROR_INV_OBJECT",
227        "The given session or object reference is " "invalid.",
228    ),
229    VI_ERROR_RSRC_LOCKED: (
230        "VI_ERROR_RSRC_LOCKED",
231        "Specified type of lock cannot be "
232        "obtained, or specified operation cannot "
233        "be performed, because the resource is "
234        "locked.",
235    ),
236    VI_ERROR_INV_EXPR: (
237        "VI_ERROR_INV_EXPR",
238        "Invalid expression specified for search.",
239    ),
240    VI_ERROR_RSRC_NFOUND: (
241        "VI_ERROR_RSRC_NFOUND",
242        "Insufficient location information or the "
243        "requested device or resource is not "
244        "present in the system.",
245    ),
246    VI_ERROR_INV_RSRC_NAME: (
247        "VI_ERROR_INV_RSRC_NAME",
248        "Invalid resource reference specified. " "Parsing error.",
249    ),
250    VI_ERROR_INV_ACC_MODE: ("VI_ERROR_INV_ACC_MODE", "Invalid access mode."),
251    VI_ERROR_TMO: ("VI_ERROR_TMO", "Timeout expired before operation " "completed."),
252    VI_ERROR_CLOSING_FAILED: (
253        "VI_ERROR_CLOSING_FAILED",
254        "The VISA driver failed to properly close "
255        "the session or object reference. This "
256        "might be due to an error freeing internal "
257        "or OS resources, a failed network "
258        "connection, or a lower-level driver or OS "
259        "error.",
260    ),
261    VI_ERROR_INV_DEGREE: ("VI_ERROR_INV_DEGREE", "Specified degree is invalid."),
262    VI_ERROR_INV_JOB_ID: (
263        "VI_ERROR_INV_JOB_ID",
264        "Specified job identifier is invalid.",
265    ),
266    VI_ERROR_NSUP_ATTR: (
267        "VI_ERROR_NSUP_ATTR",
268        "The specified attribute is not defined or "
269        "supported by the referenced object.",
270    ),
271    VI_ERROR_NSUP_ATTR_STATE: (
272        "VI_ERROR_NSUP_ATTR_STATE",
273        "The specified state of the attribute is "
274        "not valid, or is not supported as defined "
275        "by the object.",
276    ),
277    VI_ERROR_ATTR_READONLY: (
278        "VI_ERROR_ATTR_READONLY",
279        "The specified attribute is read-only.",
280    ),
281    VI_ERROR_INV_LOCK_TYPE: (
282        "VI_ERROR_INV_LOCK_TYPE",
283        "The specified type of lock is not " "supported by this resource.",
284    ),
285    VI_ERROR_INV_ACCESS_KEY: (
286        "VI_ERROR_INV_ACCESS_KEY",
287        "The access key to the resource associated "
288        "with the specified session is invalid.",
289    ),
290    VI_ERROR_INV_EVENT: (
291        "VI_ERROR_INV_EVENT",
292        "Specified event type is not supported by " "the resource.",
293    ),
294    VI_ERROR_INV_MECH: ("VI_ERROR_INV_MECH", "Invalid mechanism specified."),
295    VI_ERROR_HNDLR_NINSTALLED: (
296        "VI_ERROR_HNDLR_NINSTALLED",
297        "A handler was not installed.",
298    ),
299    VI_ERROR_INV_HNDLR_REF: (
300        "VI_ERROR_INV_HNDLR_REF",
301        "The given handler reference is either " "invalid or was not installed.",
302    ),
303    VI_ERROR_INV_CONTEXT: (
304        "VI_ERROR_INV_CONTEXT",
305        "Specified event context is invalid.",
306    ),
307    VI_ERROR_QUEUE_OVERFLOW: (
308        "VI_ERROR_QUEUE_OVERFLOW",
309        "The event queue for the specified type "
310        "has overflowed (usually due to previous "
311        "events not having been closed).",
312    ),
313    VI_ERROR_NENABLED: (
314        "VI_ERROR_NENABLED",
315        "You must be enabled for events of the "
316        "specified type in order to receive them.",
317    ),
318    VI_ERROR_ABORT: ("VI_ERROR_ABORT", "User abort occurred during transfer."),
319    VI_ERROR_RAW_WR_PROT_VIOL: (
320        "VI_ERROR_RAW_WR_PROT_VIOL",
321        "Violation of raw write protocol occurred " "during transfer.",
322    ),
323    VI_ERROR_RAW_RD_PROT_VIOL: (
324        "VI_ERROR_RAW_RD_PROT_VIOL",
325        "Violation of raw read protocol occurred " "during transfer.",
326    ),
327    VI_ERROR_OUTP_PROT_VIOL: (
328        "VI_ERROR_OUTP_PROT_VIOL",
329        "Device reported an output protocol error " "during transfer.",
330    ),
331    VI_ERROR_INP_PROT_VIOL: (
332        "VI_ERROR_INP_PROT_VIOL",
333        "Device reported an input protocol error " "during transfer.",
334    ),
335    VI_ERROR_BERR: ("VI_ERROR_BERR", "Bus error occurred during transfer."),
336    VI_ERROR_IN_PROGRESS: (
337        "VI_ERROR_IN_PROGRESS",
338        "Unable to queue the asynchronous "
339        "operation because there is already an "
340        "operation in progress.",
341    ),
342    VI_ERROR_INV_SETUP: (
343        "VI_ERROR_INV_SETUP",
344        "Unable to start operation because setup "
345        "is invalid (usually due to attributes "
346        "being set to an inconsistent state).",
347    ),
348    VI_ERROR_QUEUE_ERROR: (
349        "VI_ERROR_QUEUE_ERROR",
350        "Unable to queue the asynchronous "
351        "operation (usually due to the I/O "
352        "completion event not being enabled or "
353        "insufficient space in the session's "
354        "queue).",
355    ),
356    VI_ERROR_ALLOC: (
357        "VI_ERROR_ALLOC",
358        "Insufficient system resources to perform " "necessary memory allocation.",
359    ),
360    VI_ERROR_INV_MASK: ("VI_ERROR_INV_MASK", "Invalid buffer mask specified."),
361    VI_ERROR_IO: (
362        "VI_ERROR_IO",
363        "Could not perform operation because of " "I/O error.",
364    ),
365    VI_ERROR_INV_FMT: (
366        "VI_ERROR_INV_FMT",
367        "A format specifier in the format string " "is invalid.",
368    ),
369    VI_ERROR_NSUP_FMT: (
370        "VI_ERROR_NSUP_FMT",
371        "A format specifier in the format string " "is not supported.",
372    ),
373    VI_ERROR_LINE_IN_USE: (
374        "VI_ERROR_LINE_IN_USE",
375        "The specified trigger line is currently " "in use.",
376    ),
377    VI_ERROR_NSUP_MODE: (
378        "VI_ERROR_NSUP_MODE",
379        "The specified mode is not supported by " "this VISA implementation.",
380    ),
381    VI_ERROR_SRQ_NOCCURRED: (
382        "VI_ERROR_SRQ_NOCCURRED",
383        "Service request has not been received for " "the session.",
384    ),
385    VI_ERROR_INV_SPACE: ("VI_ERROR_INV_SPACE", "Invalid address space specified."),
386    VI_ERROR_INV_OFFSET: ("VI_ERROR_INV_OFFSET", "Invalid offset specified."),
387    VI_ERROR_INV_WIDTH: ("VI_ERROR_INV_WIDTH", "Invalid access width specified."),
388    VI_ERROR_NSUP_OFFSET: (
389        "VI_ERROR_NSUP_OFFSET",
390        "Specified offset is not accessible from " "this hardware.",
391    ),
392    VI_ERROR_NSUP_VAR_WIDTH: (
393        "VI_ERROR_NSUP_VAR_WIDTH",
394        "Cannot support source and destination " "widths that are different.",
395    ),
396    VI_ERROR_WINDOW_NMAPPED: (
397        "VI_ERROR_WINDOW_NMAPPED",
398        "The specified session is not currently " "mapped.",
399    ),
400    VI_ERROR_RESP_PENDING: (
401        "VI_ERROR_RESP_PENDING",
402        "A previous response is still pending, " "causing a multiple query error.",
403    ),
404    VI_ERROR_NLISTENERS: (
405        "VI_ERROR_NLISTENERS",
406        "No listeners condition is detected (both " "NRFD and NDAC are deasserted).",
407    ),
408    VI_ERROR_NCIC: (
409        "VI_ERROR_NCIC",
410        "The interface associated with this "
411        "session is not currently the controller "
412        "in charge.",
413    ),
414    VI_ERROR_NSYS_CNTLR: (
415        "VI_ERROR_NSYS_CNTLR",
416        "The interface associated with this " "session is not the system controller.",
417    ),
418    VI_ERROR_NSUP_OPER: (
419        "VI_ERROR_NSUP_OPER",
420        "The given session or object reference " "does not support this operation.",
421    ),
422    VI_ERROR_INTR_PENDING: (
423        "VI_ERROR_INTR_PENDING",
424        "An interrupt is still pending from a " "previous call.",
425    ),
426    VI_ERROR_ASRL_PARITY: (
427        "VI_ERROR_ASRL_PARITY",
428        "A parity error occurred during transfer.",
429    ),
430    VI_ERROR_ASRL_FRAMING: (
431        "VI_ERROR_ASRL_FRAMING",
432        "A framing error occurred during transfer.",
433    ),
434    VI_ERROR_ASRL_OVERRUN: (
435        "VI_ERROR_ASRL_OVERRUN",
436        "An overrun error occurred during "
437        "transfer. A character was not read from "
438        "the hardware before the next character "
439        "arrived.",
440    ),
441    VI_ERROR_TRIG_NMAPPED: (
442        "VI_ERROR_TRIG_NMAPPED",
443        "The path from trigSrc to trigDest is not " "currently mapped.",
444    ),
445    VI_ERROR_NSUP_ALIGN_OFFSET: (
446        "VI_ERROR_NSUP_ALIGN_OFFSET",
447        "The specified offset is not properly "
448        "aligned for the access width of the "
449        "operation.",
450    ),
451    VI_ERROR_USER_BUF: (
452        "VI_ERROR_USER_BUF",
453        "A specified user buffer is not valid or "
454        "cannot be accessed for the required size.",
455    ),
456    VI_ERROR_RSRC_BUSY: (
457        "VI_ERROR_RSRC_BUSY",
458        "The resource is valid, but VISA cannot " "currently access it.",
459    ),
460    VI_ERROR_NSUP_WIDTH: (
461        "VI_ERROR_NSUP_WIDTH",
462        "Specified width is not supported by this " "hardware.",
463    ),
464    VI_ERROR_INV_PARAMETER: (
465        "VI_ERROR_INV_PARAMETER",
466        "The value of some parameter (which " "parameter is not known) is invalid.",
467    ),
468    VI_ERROR_INV_PROT: ("VI_ERROR_INV_PROT", "The protocol specified is invalid."),
469    VI_ERROR_INV_SIZE: ("VI_ERROR_INV_SIZE", "Invalid size of window specified."),
470    VI_ERROR_WINDOW_MAPPED: (
471        "VI_ERROR_WINDOW_MAPPED",
472        "The specified session currently contains " "a mapped window.",
473    ),
474    VI_ERROR_NIMPL_OPER: (
475        "VI_ERROR_NIMPL_OPER",
476        "The given operation is not implemented.",
477    ),
478    VI_ERROR_INV_LENGTH: ("VI_ERROR_INV_LENGTH", "Invalid length specified."),
479    VI_ERROR_INV_MODE: ("VI_ERROR_INV_MODE", "Invalid mode specified."),
480    VI_ERROR_SESN_NLOCKED: (
481        "VI_ERROR_SESN_NLOCKED",
482        "The current session did not have a lock " "on the resource.",
483    ),
484    VI_ERROR_MEM_NSHARED: (
485        "VI_ERROR_MEM_NSHARED",
486        "The device does not export any memory.",
487    ),
488    VI_ERROR_LIBRARY_NFOUND: (
489        "VI_ERROR_LIBRARY_NFOUND",
490        "A code library required by VISA could not " "be located or loaded.",
491    ),
492    VI_ERROR_NSUP_INTR: (
493        "VI_ERROR_NSUP_INTR",
494        "The interface cannot generate an "
495        "interrupt on the requested level or with "
496        "the requested statusID value.",
497    ),
498    VI_ERROR_INV_LINE: (
499        "VI_ERROR_INV_LINE",
500        "The value specified by the line parameter " "is invalid.",
501    ),
502    VI_ERROR_FILE_ACCESS: (
503        "VI_ERROR_FILE_ACCESS",
504        "An error occurred while trying to open "
505        "the specified file. Possible reasons "
506        "include an invalid path or lack of access "
507        "rights.",
508    ),
509    VI_ERROR_FILE_IO: (
510        "VI_ERROR_FILE_IO",
511        "An error occurred while performing I/O on " "the specified file.",
512    ),
513    VI_ERROR_NSUP_LINE: (
514        "VI_ERROR_NSUP_LINE",
515        "One of the specified lines (trigSrc or "
516        "trigDest) is not supported by this VISA "
517        "implementation, or the combination of "
518        "lines is not a valid mapping.",
519    ),
520    VI_ERROR_NSUP_MECH: (
521        "VI_ERROR_NSUP_MECH",
522        "The specified mechanism is not supported " "for the given event type.",
523    ),
524    VI_ERROR_INTF_NUM_NCONFIG: (
525        "VI_ERROR_INTF_NUM_NCONFIG",
526        "The interface type is valid but the "
527        "specified interface number is not "
528        "configured.",
529    ),
530    VI_ERROR_CONN_LOST: (
531        "VI_ERROR_CONN_LOST",
532        "The connection for the given session has " "been lost.",
533    ),
534    VI_ERROR_MACHINE_NAVAIL: (
535        "VI_ERROR_MACHINE_NAVAIL",
536        "The remote machine does not exist or is "
537        "not accepting any connections. If the "
538        "NI-VISA server is installed and running "
539        "on the remote machine, it may have an "
540        "incompatible version or may be listening "
541        "on a different port.",
542    ),
543    VI_ERROR_NPERMISSION: (
544        "VI_ERROR_NPERMISSION",
545        "Access to the resource or remote machine "
546        "is denied. This is due to lack of "
547        "sufficient privileges for the current "
548        "user or machine",
549    ),
550}
551
552
553default_warnings = frozenset(
554    [
555        StatusCode.success_max_count_read,
556        StatusCode.success_device_not_present,
557        StatusCode.success_synchronous,
558        StatusCode.warning_queue_overflow,
559        StatusCode.warning_configuration_not_loaded,
560        StatusCode.warning_null_object,
561        StatusCode.warning_nonsupported_attribute_state,
562        StatusCode.warning_unknown_status,
563        StatusCode.warning_unknown_status,
564        StatusCode.warning_nonsupported_buffer,
565        StatusCode.warning_ext_function_not_implemented,
566    ]
567)
568
569
570class Error(Exception):
571    """Abstract basic exception class for this module."""
572
573    pass
574
575
576class VisaIOError(Error):
577    """Exception class for VISA I/O errors.
578
579    Please note that all values for "error_code" are negative according to the
580    specification (VPP-4.3.2, observation 3.3.2) and the NI implementation.
581
582    """
583
584    def __init__(self, error_code: int) -> None:
585        abbreviation, description = completion_and_error_messages.get(
586            error_code, ("?", "Unknown code.")
587        )
588        super(VisaIOError, self).__init__(
589            "%s (%d): %s" % (abbreviation, error_code, description)
590        )
591        self.error_code = error_code
592        self.abbreviation = abbreviation
593        self.description = description
594
595    def __reduce__(self) -> Tuple[type, Tuple[int]]:
596        """Store the error code when pickling."""
597        return (VisaIOError, (self.error_code,))
598
599
600class VisaIOWarning(Warning):
601    """Exception class for VISA I/O warnings.
602
603    According to the specification VPP-4.3.2 and the NI implementation.
604
605    """
606
607    def __init__(self, error_code: int) -> None:
608        abbreviation, description = completion_and_error_messages.get(
609            error_code, ("?", "Unknown code.")
610        )
611        super(VisaIOWarning, self).__init__(
612            "%s (%d): %s" % (abbreviation, error_code, description)
613        )
614        self.error_code = error_code
615        self.abbreviation = abbreviation
616        self.description = description
617
618    def __reduce__(self) -> Tuple[type, Tuple[int]]:
619        """Store the error code when pickling."""
620        return (VisaIOWarning, (self.error_code,))
621
622
623class VisaTypeError(Error):
624    """Exception class for wrong types in VISA function argument lists.
625
626    Raised if unsupported types are given to scanf, sscanf, printf, sprintf,
627    and queryf.  Because the current implementation doesn't analyse the format
628    strings, it can only deal with integers, floats, and strings.
629
630    Additionally, this exception is raised by install_handler if un unsupported
631    type is used for the user handle.
632
633    """
634
635
636class UnknownHandler(Error):
637    """Exception class for invalid handler data given to uninstall_handler().
638
639    uninstall_handler() checks whether the handler and user_data parameters
640    point to a known handler previously installed with install_handler().  If
641    it can't find it, this exception is raised.
642
643    """
644
645    def __init__(
646        self, event_type: EventType, handler: typing.VISAHandler, user_handle: Any
647    ) -> None:
648        super(UnknownHandler, self).__init__(
649            "%s, %s, %s" % (event_type, handler, user_handle)
650        )
651        self.event_type = event_type
652        self.handler = handler
653        self.user_handle = user_handle
654
655    def __reduce__(self) -> Tuple[type, tuple]:
656        """Store the event type, handler and user handle when pickling."""
657        return (UnknownHandler, (self.event_type, self.handler, self.user_handle))
658
659
660class OSNotSupported(Error):
661    """Exception used when dealing with an unsuported OS."""
662
663    def __init__(self, os: str) -> None:
664        super(OSNotSupported, self).__init__(os + " is not yet supported by PyVISA")
665        self.os = os
666
667    def __reduce__(self) -> Tuple[type, Tuple[str]]:
668        """Store the os name when pickling."""
669        return (OSNotSupported, (self.os,))
670
671
672class InvalidBinaryFormat(Error):
673    """Exception used when the specified binary format is incorrect."""
674
675    def __init__(self, description: str = "") -> None:
676        desc = ": " + description if description else ""
677        super(InvalidBinaryFormat, self).__init__(
678            "Unrecognized binary data format" + desc
679        )
680        self.description = description
681
682    def __reduce__(self) -> Tuple[type, tuple]:
683        """Store the description when pickling."""
684        return (InvalidBinaryFormat, (self.description,))
685
686
687class InvalidSession(Error):
688    """Exception raised when an invalid session is requested."""
689
690    def __init__(self) -> None:
691        super(InvalidSession, self).__init__(
692            "Invalid session handle. The resource might be closed."
693        )
694
695    def __reduce__(self) -> Tuple[type, tuple]:
696        """Nothing to store when pickling."""
697        return (InvalidSession, ())
698
699
700class LibraryError(OSError, Error):
701    """Exception used when an issue occurs loading the VISA library."""
702
703    @classmethod
704    def from_exception(cls, exc: Exception, filename: str) -> "LibraryError":
705        """Build the exception from a lower level exception."""
706        try:
707            msg = str(exc)
708
709            if ": image not found" in msg:
710                msg = " File not found or not readable."
711
712            elif ": no suitable image found" in msg:
713                if "no matching architecture" in msg:
714                    return LibraryError.from_wrong_arch(filename)
715                else:
716                    msg = "Could not determine filetype."
717
718            elif "wrong ELF class" in msg:
719                return LibraryError.from_wrong_arch(filename)
720        except UnicodeDecodeError:
721            return cls("Error while accessing %s." % filename)
722
723        return cls("Error while accessing %s: %s" % (filename, msg))
724
725    @classmethod
726    def from_wrong_arch(cls, filename: str) -> "LibraryError":
727        """Build the exception when the library has a mismatched architecture."""
728        s = ""
729        details = util.get_system_details(backends=False)
730        visalib = util.LibraryPath(
731            filename, "user" if filename == util.read_user_library_path() else "auto"
732        )
733        s += "No matching architecture.\n"
734        s += "    Current Python interpreter is %s bits\n" % details["bits"]
735        s += "    The library in: %s\n" % visalib.path
736        s += "      found by: %s\n" % visalib.found_by
737        s += "      bitness: %s\n" % visalib.bitness
738
739        return cls("Error while accessing %s: %s" % (filename, s))
740
741
742# TODO remove when removing return handler
743def _args_to_str(args: tuple, kwargs: dict) -> str:  # pragma: no cover
744    return "args=%s, kwargs=%s" % (args, kwargs)
745
746
747def return_handler(module_logger, first_is_session=True):  # pragma: no cover
748    """Decorate a VISA library function returning an error code."""
749    warnings.warn("return_handler will be removed in 1.12", FutureWarning)
750
751    def _outer(visa_library_method):
752        def _inner(self, session, *args, **kwargs):
753
754            ret_value = visa_library_method(*args, **kwargs)
755            module_logger.debug(
756                "%s%s -> %r",
757                visa_library_method.__name__,
758                _args_to_str(args, kwargs),
759                ret_value,
760            )
761
762            try:
763                ret_value = StatusCode(ret_value)
764            except ValueError:
765                pass
766
767            if first_is_session:
768                self._last_status = ret_value
769                self._last_status_in_session[session] = ret_value
770
771            if ret_value < 0:
772                raise VisaIOError(ret_value)
773
774            if ret_value in self.issue_warning_on:
775                if (
776                    session
777                    and ret_value not in self._ignore_warning_in_session[session]
778                ):
779                    module_logger.warn(VisaIOWarning(ret_value), stacklevel=2)
780
781            return ret_value
782
783        return _inner
784
785    return _outer
786