Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add null support for constants and defaults #208

Open
wants to merge 1 commit into
base: rolling
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion rosidl_generator_py/resource/_msg.py.em
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ for member in message.structure.members:
'import builtins', []) # used for @builtins.property
if isinstance(type_, BasicType) and type_.typename in FLOATING_POINT_TYPES:
imports.setdefault(
'import math', []) # used for math.isinf
'import math', []) # used for math.isinf, math.nan
if (
isinstance(member.type, AbstractNestedType) and
isinstance(member.type.value_type, BasicType) and
Expand Down Expand Up @@ -405,6 +405,11 @@ if isinstance(type_, AbstractNestedType):
if all(self.@(member.name) != other.@(member.name)):
@[ else]@
if self.@(member.name) != other.@(member.name):
@[ if isinstance(member.type, BasicType) and member.type.typename in FLOATING_POINT_TYPES ]@
# Handle special case for IEE-754 floating point NaN not equaling itself.
if math.isnan(self.@(member.name)) and math.isnan(other.@(member.name)):
return True
@[ end if]@
@[ end if]@
return False
@[end for]@
Expand Down
12 changes: 10 additions & 2 deletions rosidl_generator_py/rosidl_generator_py/generate_py_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from ast import literal_eval
import keyword
import math
import os
import pathlib
import sys
Expand Down Expand Up @@ -246,7 +247,7 @@ def primitive_value_to_py(type_, value):
return repr(bytes([value]))

if type_.typename in FLOATING_POINT_TYPES:
return '%s' % value
return floating_point_to_py(value)

assert False, "unknown primitive type '%s'" % type_.typename

Expand All @@ -268,14 +269,21 @@ def constant_value_to_py(type_, value):
return repr(bytes([value]))

if type_.typename in FLOATING_POINT_TYPES:
return '%s' % value
return floating_point_to_py(value)

if isinstance(type_, AbstractGenericString):
return quoted_string(value)

assert False, "unknown constant type '%s'" % type_


def floating_point_to_py(value):
if math.isnan(float(value)):
return 'math.nan'
else:
return '%s' % value


def quoted_string(s):
s = s.replace('\\', '\\\\')
# strings containing single quote but no double quotes can be wrapped in
Expand Down
28 changes: 28 additions & 0 deletions rosidl_generator_py/test/test_generate_py_impl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2016-2019 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


from rosidl_generator_py.generate_py_impl import floating_point_to_py


def test_floating_point_to_py():

# normal floating point values
assert floating_point_to_py("1.0") == "1.0"
assert floating_point_to_py("-42.0") == "-42.0"

# NaN's
assert floating_point_to_py("NaN") == "math.nan"
assert floating_point_to_py("nan") == "math.nan"
assert floating_point_to_py("NAN") == "math.nan"
11 changes: 11 additions & 0 deletions rosidl_generator_py/test/test_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,12 @@ def test_basic_types():
assert 42 == msg.char_value
msg.float32_value = 1.125
assert 1.125 == msg.float32_value
msg.float32_value = math.nan
assert math.isnan(msg.float32_value)
msg.float64_value = 1.125
assert 1.125 == msg.float64_value
msg.float64_value = math.nan
assert math.isnan(msg.float64_value)
msg.int8_value = -50
assert -50 == msg.int8_value
msg.uint8_value = 200
Expand Down Expand Up @@ -130,22 +134,29 @@ def test_basic_types():
setattr(msg, 'float64_value', float64_ieee_max_next)

# NaN
# Test IEEE-754 message equality when values are NaN.
setattr(msg, 'float32_value', math.nan)
assert math.isnan(msg.float32_value)
assert msg == msg
setattr(msg, 'float64_value', math.nan)
assert math.isnan(msg.float64_value)
assert msg == msg

# -Inf
setattr(msg, 'float32_value', -math.inf)
assert math.isinf(msg.float32_value)
assert msg == msg
setattr(msg, 'float64_value', -math.inf)
assert math.isinf(msg.float64_value)
assert msg == msg

# +Inf
setattr(msg, 'float32_value', math.inf)
assert math.isinf(msg.float32_value)
assert msg == msg
setattr(msg, 'float64_value', math.inf)
assert math.isinf(msg.float64_value)
assert msg == msg


def test_strings():
Expand Down