Message equality fails with NaN values for floats/doubles
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 35/100
Hướng nghiên cứu
Bắt đầu với commit nan-failed-comparison và trường hợp test_basic_types bị lỗi được nêu trong báo cáo. Truy vết đường dẫn so sánh bằng nhau của message được rosidl_generator_py sử dụng cho các trường float, sau đó chạy test liên quan để xác nhận rằng các message có cùng nội dung NaN được so sánh là bằng nhau.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Bug report
Required Info:
- Operating System:
- Ubuntu 22.04
- Installation type:
- Binaries and Source
- Version or commit hash:
- 0.14.4
- DDS implementation:
- N/A
- Client library (if applicable):
- N/A
Steps to reproduce issue
See the commit on equality which causes the tests to fail on branch nan-failed-comparison
Expected behavior
When floating point values are set to NaN, and the == equality operator is used to check messages are equal, it should return true when two messages have the same contents
Actual behavior
NaN's don't equal themselves, and the message equality evaluates as False.
Additional information
See https://github.com/ros2/rosidl/pull/789#issuecomment-2000037932
I have a fix internally, I just need approval to share it open source.
Test Logs
21: =================================== FAILURES ===================================
21: _______________________________ test_basic_types _______________________________
21:
21: def test_basic_types():
21: msg = BasicTypes()
21:
21: # types
21: assert isinstance(msg.bool_value, bool)
21: assert isinstance(msg.byte_value, bytes)
21: assert 1 == len(msg.byte_value)
21: # for legacy reasons, 'char' from a .msg interface maps to 'uint8'
21: assert isinstance(msg.char_value, int)
21: assert isinstance(msg.float32_value, float)
21: assert isinstance(msg.float64_value, float)
21: assert isinstance(msg.int8_value, int)
21: assert isinstance(msg.uint8_value, int)
21: assert isinstance(msg.int16_value, int)
21: assert isinstance(msg.uint16_value, int)
21: assert isinstance(msg.int32_value, int)
21: assert isinstance(msg.uint32_value, int)
21: assert isinstance(msg.int64_value, int)
21: assert isinstance(msg.uint64_value, int)
21:
21: # default values
21: assert msg.bool_value is False
21: assert bytes([0]) == msg.byte_value
21: assert 0 == msg.char_value
21: assert 0.0 == msg.float32_value
21: assert 0.0 == msg.float64_value
21: assert 0 == msg.int8_value
21: assert 0 == msg.uint8_value
21: assert 0 == msg.int16_value
21: assert 0 == msg.uint16_value
21: assert 0 == msg.int32_value
21: assert 0 == msg.uint32_value
21: assert 0 == msg.int64_value
21: assert 0 == msg.uint64_value
21:
21: # assignment
21: msg.bool_value = True
21: assert msg.bool_value is True
21: msg.byte_value = b'2'
21: assert bytes([50]) == msg.byte_value
21: msg.char_value = 42
21: assert 42 == msg.char_value
21: msg.float32_value = 1.125
21: assert 1.125 == msg.float32_value
21: msg.float64_value = 1.125
21: assert 1.125 == msg.float64_value
21: msg.int8_value = -50
21: assert -50 == msg.int8_value
21: msg.uint8_value = 200
21: assert 200 == msg.uint8_value
21: msg.int16_value = -1000
21: assert -1000 == msg.int16_value
21: msg.uint16_value = 2000
21: assert 2000 == msg.uint16_value
21: msg.int32_value = -30000
21: assert -30000 == msg.int32_value
21: msg.uint32_value = 60000
21: assert 60000 == msg.uint32_value
21: msg.int64_value = -40000000
21: assert -40000000 == msg.int64_value
21: msg.uint64_value = 50000000
21: assert 50000000 == msg.uint64_value
21:
21: # out of range
21: with pytest.raises(AssertionError):
21: setattr(msg, 'char_value', '\x80')
21: for i in [8, 16, 32, 64]:
21: with pytest.raises(AssertionError):
21: setattr(msg, 'int%d_value' % i, 2**(i - 1))
21: with pytest.raises(AssertionError):
21: setattr(msg, 'int%d_value' % i, -2**(i - 1) - 1)
21: with pytest.raises(AssertionError):
21: setattr(msg, 'uint%d_value' % i, -1)
21: with pytest.raises(AssertionError):
21: setattr(msg, 'int%d_value' % i, 2**i)
21: float32_ieee_max_next = numpy.nextafter(3.402823466e+38, math.inf)
21: with pytest.raises(AssertionError):
21: setattr(msg, 'float32_value', -float32_ieee_max_next)
21: with pytest.raises(AssertionError):
21: setattr(msg, 'float32_value', float32_ieee_max_next)
21:
21: # Only run bounds test on system with non-compliant IEEE 754 float64.
21: # Otherwise the number is implicitly converted to inf.
21: if sys.float_info.max > 1.7976931348623157e+308:
21: float64_ieee_max_next = numpy.nextafter(1.7976931348623157e+308, math.inf)
21: with pytest.raises(AssertionError):
21: setattr(msg, 'float64_value', -float64_ieee_max_next)
21: with pytest.raises(AssertionError):
21: setattr(msg, 'float64_value', float64_ieee_max_next)
21:
21: # NaN
21: setattr(msg, 'float32_value', math.nan)
21: assert math.isnan(msg.float32_value)
21: > assert msg == msg
21: E AssertionError: assert rosidl_generator_py.msg.BasicTypes(bool_value=True, byte_value=b'2', char_value=42, float32_value=nan, float64_value=1...6_value=-1000, uint16_value=2000, int32_value=-30000, uint32_value=60000, int64_value=-40000000, uint64_value=50000000) == rosidl_generator_py.msg.BasicTypes(bool_value=True, byte_value=b'2', char_value=42, float32_value=nan, float64_value=1...6_value=-1000, uint16_value=2000, int32_value=-30000, uint32_value=60000, int64_value=-40000000, uint64_value=50000000)
- Ngôn ngữ chính
- EmberScript
- Star
- 26
- Fork
- 68
- Merge trung bình
- 1 ngày 9 giờ
- Pull request đã merge (30 ngày)
- 3
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của ros2/rosidl_python
-
Eliminate array resetting loop in _msg_support.c.emCó thể đã có người làm @Lidang-Jiang đã nhận 171 ngày trước. Đang mởenhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
ros2/rosidl_python#255 · 1 reaction ·
-
bug
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 56/100
ros2/rosidl_python#264 · 2 bình luận ·
-
Message named pkg/Duration with field builtin_interfaces/Duration is invalidCó thể đã có người làm @Lidang-Jiang đã nhận 171 ngày trước. Đang mởbug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
ros2/rosidl_python#257 · 8 bình luận ·
-
enhancement
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
ros2/rosidl_python#242 ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 32/100
ros2/rosidl_python#219 · 2 bình luận ·
Tất cả issue của ros2/rosidl_python
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
kellyjonbrazil/jc#788 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
bug p2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
bastani-inc/atomic#3703 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 60/100
calcit-lang/js-ffi#178 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày