Skip to content

Commit

Permalink
Merge #456
Browse files Browse the repository at this point in the history
456: Change ni to ivi backend name "Reduce bias towards National Instruments (issue 455)" r=MatthieuDartiailh a=DSTHub

I made change in:

- 'highlevel.py' more precisely in list_backends(),  get_wrapper_class() and _get_default_wrapper() functions. 
- 'visa.py'
- Docs files

To my mind it's enough. 
Of course, I tested it as much as I could.
![testing](https://user-images.githubusercontent.com/42816781/63608113-d47dc500-c5dc-11e9-983d-d11670a7716e.PNG)
![fixed](https://user-images.githubusercontent.com/42816781/63608173-fc6d2880-c5dc-11e9-8c17-7e29011abc1f.PNG)

I'm not sure about docs, please double check it.



Co-authored-by: Dmitry Stepanov <ateds@list.ru>
Co-authored-by: MatthieuDartiailh <marul@laposte.net>
  • Loading branch information
3 people committed Sep 18, 2019
2 parents ecfb1fa + 3e45eca commit b34e029
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 49 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ PyVISA Changelog
1.11 (unreleased)
-----------------

- Make the library less biased towards National Instrument by referring to IVI
where relevant PR #456

1.10.1 (2019-09-11)
-------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/source/advanced/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ given resource, you will use the |open_resource| method to obtain the
appropriate object. If needed, you will be able to access the ``VisaLibrary``
object directly using the |visalib| attribute.

The ``VisaLibrary`` does the low-level calls. In the default NI Backend,
The ``VisaLibrary`` does the low-level calls. In the default IVI Backend,
levels 1 and 2 are implemented in the same package called
:mod:`pyvisa.ctwrapper` (which stands for ctypes wrapper). This package is
included in PyVISA.
Expand Down
12 changes: 7 additions & 5 deletions docs/source/advanced/backends.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,26 @@ Users had to change their programs to use other packages with different API.
Since 1.6, PyVISA is a frontend to VISA. It provides a nice, Pythonic API and
can connect to multiple backends. Each backend exposes a class derived from
VisaLibraryBase that implements the low-level communication. The ctypes wrapper
around NI-VISA is the default backend (called **ni**) and is bundled with
PyVISA for simplicity.
around IVI-VISA is the default backend (called **ivi**) and is bundled with
PyVISA for simplicity. In general, IVI-VISA can be NI-VISA, Keysight VISA,
R&S VISA, tekVISA etc.
By default, it calls the library that is installed on your system as VISA library.

You can specify the backend to use when you instantiate the resource manager
using the ``@`` symbol. Remembering that **ni** is the default, this::
using the ``@`` symbol. Remembering that **ivi** is the default, this::

>>> import visa
>>> rm = visa.ResourceManager()

is the same as this::

>>> import visa
>>> rm = visa.ResourceManager('@ni')
>>> rm = visa.ResourceManager('@ivi')

You can still provide the path to the library if needed::

>>> import visa
>>> rm = visa.ResourceManager('/path/to/lib@ni')
>>> rm = visa.ResourceManager('/path/to/lib@ivi')

Under the hood, the |ResourceManager| looks for the requested backend and
instantiate the VISA library that it provides.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/introduction/communication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This example already shows the two main design goals of PyVISA: preferring
simplicity over generality, and doing it the object-oriented way.

After importing ``visa``, we create a ``ResourceManager`` object. If called
without arguments, PyVISA will prefer the default backend (NI) which tries to
without arguments, PyVISA will prefer the default backend (IVI) which tries to
find the VISA shared library for you. If it fails it will fall back to
pyvisa-py if installed. You can check what backend is used and the location of
the shared library used, if relevant, simply by:
Expand Down
16 changes: 9 additions & 7 deletions docs/source/introduction/configuring.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ Configuring the backend
.. include:: ../substitutions.sub

Currently there are two backends available: The one included in pyvisa, which
uses the NI library, and the backend provided by pyvisa-py, which is a pure
python implementation of the VISA library. If no backend is specified, pyvisa
uses the NI backend if the NI library has been installed (see next section for
details). Failing that, it uses the pyvisa-py backend.
uses the IVI library (include NI-VISA, Keysight VISA, R&S VISA, tekVISA etc.),
and the backend provided by pyvisa-py, which is a pure python implementation
of the VISA library. If no backend is specified, pyvisa uses the IVI backend
if any IVI library has been installed (see next section for details).
Failing that, it uses the pyvisa-py backend.

You can also select a desired backend by passing a parameter to the
ResourceManager, shown here for pyvisa-py:
Expand All @@ -19,13 +20,14 @@ ResourceManager, shown here for pyvisa-py:
Alternatively it can also be selected by setting the environment variable
PYVISA_LIBRARY. It takes the same values as the ResourceManager constructor.

Configuring the NI backend
Configuring the IVI backend
--------------------------

.. note::

The NI backend requires that you install first the NI-VISA library. You can
get info here: (:ref:`faq-getting-nivisa`)
The IVI backend requires that you install first the IVI-VISA library.
For example you can use NI-VISA or any other library in your opinion.
about NI-VISA get info here: (:ref:`faq-getting-nivisa`)


In most cases PyVISA will be able to find the location of the shared visa
Expand Down
2 changes: 1 addition & 1 deletion docs/source/introduction/shell.rst
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ or::

pyvisa-shell -b py

uses python-py as backend instead of ni backend, for situation when ni not
uses python-py as backend instead of ivi backend, for situation when ivi not
installed.


Expand Down
5 changes: 2 additions & 3 deletions pyvisa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
pyvisa
~~~~~~
Python wrapper of National Instrument (NI) Virtual Instruments Software
Architecture library (VISA).
Python wrapper of IVI Virtual Instruments Software Architecture library (VISA).
This file is part of PyVISA.
:copyright: 2014 by PyVISA Authors, see AUTHORS for more details.
:copyright: 2014-2019 by PyVISA Authors, see AUTHORS for more details.
:license: MIT, see LICENSE for more details.
"""

Expand Down
8 changes: 4 additions & 4 deletions pyvisa/ctwrapper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
pyvisa.ctwrapper
~~~~~~~~~~~~~~~~
ctypes wrapper for NI-VISA library.
ctypes wrapper for IVI-VISA library.
This file is part of PyVISA.
:copyright: 2014 by PyVISA Authors, see AUTHORS for more details.
:copyright: 2014-2019 by PyVISA Authors, see AUTHORS for more details.
:license: MIT, see LICENSE for more details.
"""

from __future__ import division, unicode_literals, print_function, absolute_import

from .highlevel import NIVisaLibrary
from .highlevel import IVIVisaLibrary

WRAPPER_CLASS = NIVisaLibrary
WRAPPER_CLASS = IVIVisaLibrary

47 changes: 39 additions & 8 deletions pyvisa/ctwrapper/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from . import functions


logger = logging.LoggerAdapter(logger, {'backend': 'ni'})
logger = logging.LoggerAdapter(logger, {'backend': 'ivi'})


def add_visa_methods(aclass):
Expand Down Expand Up @@ -51,19 +51,19 @@ def unique(seq):


@add_visa_methods
class NIVisaLibrary(highlevel.VisaLibraryBase):
"""High level NI-VISA Library wrapper using ctypes.
class IVIVisaLibrary(highlevel.VisaLibraryBase):
"""High level IVI-VISA Library wrapper using ctypes.
The easiest way to instantiate the library is to let `pyvisa` find the
right one for you. This looks first in your configuration file (~/.pyvisarc).
If it fails, it uses `ctypes.util.find_library` to try to locate a library
in a way similar to what the compiler does:
>>> visa_library = NIVisaLibrary()
>>> visa_library = IVIVisaLibrary()
But you can also specify the path:
>>> visa_library = NIVisaLibrary('/my/path/visa.so')
>>> visa_library = IVIVisaLibrary('/my/path/visa.so')
:param library_path: path of the VISA library.
"""
Expand All @@ -77,7 +77,7 @@ def get_library_paths():

from ..util import LibraryPath, read_user_library_path

# Try to find NI libraries using known names.
# Try to find IVI libraries using known names.
tmp = [find_library(library_path)
for library_path in ('visa', 'visa32', 'visa32.dll', 'visa64', 'visa64.dll')]

Expand All @@ -98,19 +98,20 @@ def get_library_paths():
@staticmethod
def get_debug_info():
"""Return a list of lines with backend info.
"""
from pyvisa import __version__
d = OrderedDict()
d['Version'] = '%s (bundled with PyVISA)' % __version__

paths = NIVisaLibrary.get_library_paths()
paths = IVIVisaLibrary.get_library_paths()

for ndx, visalib in enumerate(paths, 1):
nfo = OrderedDict()
nfo['found by'] = visalib.found_by
nfo['bitness'] = visalib.bitness
try:
lib = NIVisaLibrary(visalib)
lib = IVIVisaLibrary(visalib)
sess, _ = lib.open_default_resource_manager()
nfo['Vendor'] = str(lib.get_attribute(sess, constants.VI_ATTR_RSRC_MANF_NAME)[0])
nfo['Impl. Version'] = str(lib.get_attribute(sess, constants.VI_ATTR_RSRC_IMPL_VERSION)[0])
Expand Down Expand Up @@ -259,3 +260,33 @@ def list_resources(self, session, query='?*::INSTR'):

return tuple(resource for resource in resources)


class NIVisaLibrary(IVIVisaLibrary):
"""Deprecated name for IVIVisaLibrary.
This class will be removed in 1.12
"""
@staticmethod
def get_library_paths():
"""Return a tuple of possible library paths.
:rtype: tuple
"""
warnings.warn("NIVisaLibrary is deprecated and will be removed in 1.12. "
"Use IVIVisaLibrary instead.", FutureWarning)
IVIVisaLibrary.get_library_paths()

@staticmethod
def get_debug_info():
"""Return a list of lines with backend info.
"""
warnings.warn("NIVisaLibrary is deprecated and will be removed in 1.12. "
"Use IVIVisaLibrary instead.", FutureWarning)
IVIVisaLibrary.get_debug_info()

def __new__(cls, library_path=''):
warnings.warn("NIVisaLibrary is deprecated and will be removed in 1.12. "
"Use IVIVisaLibrary instead.", FutureWarning)
IVIVisaLibrary.__new__(cls, library_path)
50 changes: 32 additions & 18 deletions pyvisa/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import collections
import pkgutil
import os
import warnings
from collections import defaultdict
from weakref import WeakSet

Expand Down Expand Up @@ -47,8 +48,9 @@ class VisaLibraryBase(object):
to the underlying devices providing Pythonic wrappers to VISA functions. But not all
derived class must/will implement all methods.
The default VisaLibrary class is :class:`pyvisa.ctwrapper.highlevel.NIVisaLibrary`,
which implements a ctypes wrapper around the NI-VISA library.
The default VisaLibrary class is :class:`pyvisa.ctwrapper.highlevel.IVIVisaLibrary`,
which implements a ctypes wrapper around the IVI-VISA library.
Certainly, IVI-VISA can be NI-VISA, Keysight VISA, R&S VISA, tekVISA etc.
In general, you should not instantiate it directly. The object exposed to the user
is the :class:`pyvisa.highlevel.ResourceManager`. If needed, you can access the
Expand Down Expand Up @@ -1440,9 +1442,8 @@ def list_backends():
:rtype: list
"""
return ['ni'] + [name for (loader, name, ispkg) in pkgutil.iter_modules()
if name.startswith('pyvisa-') and not name.endswith('-script')]

return ['ivi'] + [name for (loader, name, ispkg) in pkgutil.iter_modules()
if name.startswith('pyvisa-') and not name.endswith('-script')]

#: Maps backend name to VisaLibraryBase derived class
#: dict[str, :class:`pyvisa.highlevel.VisaLibraryBase`]
Expand All @@ -1452,15 +1453,24 @@ def list_backends():
def get_wrapper_class(backend_name):
"""Return the WRAPPER_CLASS for a given backend.
backend_name == 'ni' is used for backwards compatibility
and will be removed in 1.12.
:rtype: pyvisa.highlevel.VisaLibraryBase
"""
try:
return _WRAPPERS[backend_name]
except KeyError:
if backend_name == 'ni':
from .ctwrapper import NIVisaLibrary
_WRAPPERS['ni'] = NIVisaLibrary
return NIVisaLibrary
if backend_name == 'ivi' or backend_name == 'ni':
from .ctwrapper import IVIVisaLibrary
_WRAPPERS['ivi'] = IVIVisaLibrary
if backend_name == 'ni':
warnings.warn(
'@ni backend name is deprecated and will be '
'removed in 1.12. Use @ivi instead. '
'Check the documentation for details',
FutureWarning)
return IVIVisaLibrary

try:
pkg = __import__('pyvisa-' + backend_name)
Expand All @@ -1471,27 +1481,31 @@ def get_wrapper_class(backend_name):


def _get_default_wrapper():
"""Return an available default VISA wrapper as a string ('ni' or 'py').
"""Return an available default VISA wrapper as a string ('ivi' or 'py').
Use IVI if the binary is found, else try to use pyvisa-py.
'ni' VISA wrapper is NOT used since version > 1.10.0
and will be removed in 1.12
Use NI if the binary is found, else try to use pyvisa-py.
If neither can be found, raise a ValueError.
"""

from .ctwrapper import NIVisaLibrary
ni_binary_found = bool(NIVisaLibrary.get_library_paths())
from .ctwrapper import IVIVisaLibrary
ni_binary_found = bool(IVIVisaLibrary.get_library_paths())
if ni_binary_found:
logger.debug('The NI implementation available')
return 'ni'
logger.debug('The IVI implementation available')
return 'ivi'
else:
logger.debug('Did not find NI binary')
logger.debug('Did not find IVI binary')

try:
get_wrapper_class('py') # check for pyvisa-py availability
logger.debug('pyvisa-py is available.')
return 'py'
except ValueError:
logger.debug('Did not find pyvisa-py package')
raise ValueError('Could not locate a VISA implementation. Install either the NI binary or pyvisa-py.')
raise ValueError('Could not locate a VISA implementation. Install either the IVI binary or pyvisa-py.')


def open_visa_library(specification):
Expand All @@ -1515,7 +1529,7 @@ def open_visa_library(specification):
wrapper = None # Flag that we need a fallback, but avoid nested exceptions
if wrapper is None:
if argument: # some filename given
wrapper = 'ni'
wrapper = 'ivi'
else:
wrapper = _get_default_wrapper()

Expand Down
2 changes: 1 addition & 1 deletion visa.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def visa_main(command=None):
parser = argparse.ArgumentParser(description='PyVISA command-line utilities')

parser.add_argument('--backend', '-b', dest='backend', action='store', default=None,
help='backend to be used (default: ni)')
help='backend to be used (default: ivi)')

if not command:
subparsers = parser.add_subparsers(title='command', dest='command')
Expand Down

0 comments on commit b34e029

Please sign in to comment.