ni / nidaqmx-python

A Python API for interacting with NI-DAQmx
Other
413 stars 155 forks source link

Analog unscaled reader tests fail with NumPy 2.0 #600

Closed bkeryan closed 1 month ago

bkeryan commented 1 month ago

After upgrading to NumPy 2.0, I get the following test failures:

tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint16___returns_valid_samples[library_init_kwargs] - assert array([[3278,... dtype=uint16) == approx([3276 ...30 ± 3.0e+00])
FAILED tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint16___returns_valid_samples[grpc_init_kwargs] - assert array([[3278,... dtype=uint16) == approx([3276 ...30 ± 3.0e+00])
FAILED tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint32___returns_valid_samples[library_init_kwargs] - assert array([[3278,... dtype=uint32) == approx([3276 ...30 ± 3.0e+00])
FAILED tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint32___returns_valid_samples[grpc_init_kwargs] - assert array([[3278,... dtype=uint32) == approx([3276 ...30 ± 3.0e+00])

Details (the other 3 are similar)

______________ test___analog_unscaled_reader___read_uint16___returns_valid_samples[library_init_kwargs] _______________

ai_multi_channel_task = Task(name=_unnamedTask<2>)

    def test___analog_unscaled_reader___read_uint16___returns_valid_samples(
        ai_multi_channel_task: nidaqmx.Task,
    ) -> None:
        reader = AnalogUnscaledReader(ai_multi_channel_task.in_stream)
        num_channels = ai_multi_channel_task.number_of_channels
        samples_to_read = 10
        data = numpy.full(
            (num_channels, samples_to_read), numpy.iinfo(numpy.uint16).min, dtype=numpy.uint16
        )

        samples_read = reader.read_uint16(data, number_of_samples_per_channel=samples_to_read)

        assert samples_read == samples_to_read
        expected_vals = [
            _get_voltage_code_offset_for_chan(chan_index) for chan_index in range(num_channels)
        ]
>       assert data == pytest.approx(expected_vals, abs=VOLTAGE_CODE_EPSILON)
E       assert array([[3278,... dtype=uint16) == approx([3276 ...30 ± 3.0e+00])
E
E         (pytest_assertion plugin: representation of details failed: D:\dev\nidaqmx-python\.venv\lib\site-packages\_pytest\python_api.py:342: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
E          Probably an object has a faulty __repr__.)

tests\component\test_stream_readers_ai.py:215: AssertionError

There are also some warnings:

================================================== warnings summary ===================================================
tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint16___returns_valid_samples[library_init_kwargs]
_kwargs]
tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint32___returns_valid_samples[library_init_kwargs]
tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint32___returns_valid_samples[grpc_init_kwargs]
  D:\dev\nidaqmx-python\.venv\lib\site-packages\_pytest\python_api.py:457: RuntimeWarning: overflow encountered in scalar subtract
    result: bool = abs(self.expected - actual) <= self.tolerance  # type: ignore[arg-type]

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
bkeryan commented 1 month ago

Only the tests for the unsigned integer types are failing. The tests for signed integer types still pass.

This seems to be due to https://numpy.org/devdocs/numpy_2_0_migration_guide.html#changes-to-numpy-data-type-promotion

Calling numpy._set_promotion_state("weak_and_warn") produces more descriptive warnings:

tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint16___returns_valid_samples[library_init_kwargs]
tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint16___returns_valid_samples[grpc_init_kwargs]
  D:\dev\nidaqmx-python\.venv\lib\site-packages\_pytest\python_api.py:457: UserWarning: result dtype changed due to the removal of value-based promotion from NumPy. Changed from int32 to uint16.
    result: bool = abs(self.expected - actual) <= self.tolerance  # type: ignore[arg-type]

tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint32___returns_valid_samples[library_init_kwargs]
tests/component/test_stream_readers_ai.py::test___analog_unscaled_reader___read_uint32___returns_valid_samples[grpc_init_kwargs]
  D:\dev\nidaqmx-python\.venv\lib\site-packages\_pytest\python_api.py:457: UserWarning: result dtype changed due to the removal of value-based promotion from NumPy. Changed from int64 to uint32.
    result: bool = abs(self.expected - actual) <= self.tolerance  # type: ignore[arg-type]

The tests pass with numpy._set_promotion_state("legacy")