Message equality fails with NaN values for floats/doubles
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 35/100
Direzione di ricerca
Inizia con il commit nan-failed-comparison e il caso test_basic_types non riuscito mostrato nel report. Traccia il percorso di uguaglianza dei messaggi utilizzato da rosidl_generator_py per i campi float, quindi esegui il test pertinente per confermare che i messaggi con lo stesso contenuto NaN risultino uguali nel confronto.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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)
- Lingua principale
- EmberScript
- Stelle
- 26
- Fork
- 68
- Merge medio
- 2g 13h
- PR unite (30g)
- 1
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di ros2/rosidl_python
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
ros2/rosidl_python#255 · 1 reazione ·
-
bug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 56/100
ros2/rosidl_python#264 · 2 commenti ·
-
bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
ros2/rosidl_python#257 · 8 commenti ·
-
enhancement
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
ros2/rosidl_python#242 ·
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 32/100
ros2/rosidl_python#219 · 2 commenti ·
Tutte le issue di ros2/rosidl_python
Issue simili
-
[Bug]: classify_items.py cron script never includes its own required JSON schema in the prompt Apertacomp/cron P2 sweeper:risk-automation type/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
NousResearch/hermes-agent#117792 · 1 commento ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
bancolombia/sentinel#20 ·
-
optimization optimization:agents-md-curator
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
githubnext/gh-aw-cao#13143 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
-
chore
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
alunduil/woodland-generators#669 ·