Skip to content

Commit

Permalink
FIX FutureWarning: Reading binary data without a known length is erro…
Browse files Browse the repository at this point in the history
…r prone, and should be avoided. This capability will will be removed in future versions.

  Additional information provided by the package: "If the instrument does not report the length of the block as part of the transfer, it may be because the size is fixed or can be accessed from the instrumentin using a specific command. You should find the expected number of points and pass it using the `data_points` keyword."
  • Loading branch information
Arkh42 committed Oct 14, 2020
1 parent 1f22529 commit 5deedab
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 11 deletions.
27 changes: 19 additions & 8 deletions rtestbench/core.py
Expand Up @@ -371,7 +371,14 @@ def query(self, request: str) -> str:
except visa.VisaIOError as err:
raise IOError("Cannot get an answer from the request {}; origin comes from {}.".format(request, err.description))

def query_data(self, request):
def query_number_data(self):
"""Queries the number of data available in the buffer.
This function must be implemented to use query_data() in binary values."""

raise NotImplementedError("This function must be implemented by daughter classes.")

def query_data(self, request, number_data="auto"):
"""Sends an SCPI request which expects data from the tool.
Returns:
Expand All @@ -397,13 +404,17 @@ def query_data(self, request):
container=self._properties.data_container
)
elif transfer_format in ("bin", "binary"):
return self._virtual_interface.query_binary_values(
request,
datatype=self._properties.bin_data_type,
is_big_endian=True if self._properties.bin_data_endianness == "big" else False,
container=self._properties.data_container,
header_fmt=self._properties.bin_data_header
)
if number_data == "auto":
number_data = int(self.query_number_data())
else:
return self._virtual_interface.query_binary_values(
request,
datatype=self._properties.bin_data_type,
is_big_endian=True if self._properties.bin_data_endianness == "big" else False,
container=self._properties.data_container,
header_fmt=self._properties.bin_data_header,
data_points=number_data
)
else:
raise NotImplementedError("Unsupported transfer format {} is currently activated.".format(transfer_format))
except visa.InvalidSession as err:
Expand Down
10 changes: 7 additions & 3 deletions rtestbench/tests/test_core.py
Expand Up @@ -542,16 +542,20 @@ def test_tool_querydata(fakeToolWithoutInterface, fakeTool):
fakeTool._properties.activated_transfer_format = "ascii"
data = fakeTool.query_data('request')

with pytest.raises(NotImplementedError): # default number_data="auto" is not implemented
fakeTool._properties.activated_transfer_format = "bin"
data = fakeTool.query_data('request')

fakeTool._properties.activated_transfer_format = "bin"
data = fakeTool.query_data('request')
data = fakeTool.query_data('request', number_data=1)

fakeTool._properties.activated_transfer_format = "binary"
data = fakeTool.query_data('request')
data = fakeTool.query_data('request', number_data=1)

# Change read termination character to generate visa.VisaIOError
fakeTool._virtual_interface.read_termination = '\r'
with pytest.raises(IOError):
answer = fakeTool.query_data('request')
answer = fakeTool.query_data('request', number_data=1)

# Close virtual interface to generate visa.InvalidSession
fakeTool._virtual_interface.close()
Expand Down
19 changes: 19 additions & 0 deletions rtestbench/tools/keysight/electrometer/b298x.py
Expand Up @@ -127,6 +127,19 @@ def __init__(self, info: ToolInfo):
)


# Generic commands
def query_number_data(self):
"""Queries the number of data available in the buffer."""

try:
number_data = self.query(":SYSTem:DATA:QUANtity?")
except IOError as err:
logging.warning("{} cannot send the number of data available!".format(self._info))
else:
logging.debug("{} is going to send data: {} expected.".format(self._info, number_data))
return number_data


# Common SCPI commands
def set_data_transfer_format(self, tsf_format: str, data_type: str):
"""Sets the data transfer format of the tool."""
Expand All @@ -146,6 +159,8 @@ def set_data_transfer_format(self, tsf_format: str, data_type: str):
raise RuntimeError("Cannot sets the data transfer format as ASCII for the tool {}.".format(self._info))
except ValueError:
raise
else:
logging.debug("The data transfer format is now ASCII.")
elif tsf_format in const.RTB_TRANSFERT_FORMAT_BIN:
if data_type in const.RTB_BIN_DATA_TYPES_FLOAT:
try:
Expand All @@ -154,13 +169,17 @@ def set_data_transfer_format(self, tsf_format: str, data_type: str):
except IOError as err:
logging.error(err)
raise RuntimeError("Cannot sets the data transfer format as bin32 for the tool {}.".format(self._info))
else:
logging.debug("The data transfer format is now binary (32 bits).")
elif data_type in const.RTB_BIN_DATA_TYPES_DOUBLE:
try:
self.send(":FORMat:DATA REAL,64")
self._properties.bin_data_type = data_type
except IOError as err:
logging.error(err)
raise RuntimeError("Cannot sets the data transfer format as bin64 for the tool {}.".format(self._info))
else:
logging.debug("The data transfer format is now binary (64 bits).")
else:
raise NotImplementedError("The data_type argument must be in {} or in {} to use binary data for the tool {}.".format(
const.RTB_BIN_DATA_TYPES_FLOAT,
Expand Down

0 comments on commit 5deedab

Please sign in to comment.