def test_load_msg_from_string(): # make sure Header -> std_msgs/Header conversion works from genmsg.msgs import Constant from genmsg.msg_loader import load_msg_from_string, MsgContext context = MsgContext.create_default() msgspec = load_msg_from_string(context, "Header header", "test_pkg/HeaderTest") print msgspec assert msgspec.has_header() assert msgspec.types == ["std_msgs/Header"] assert msgspec.names == ["header"] assert msgspec.constants == [] assert msgspec.short_name == "HeaderTest" assert msgspec.package == "test_pkg" assert msgspec.full_name == "test_pkg/HeaderTest" msgspec = load_msg_from_string(context, "int8 c=1\nHeader header\nint64 data", "test_pkg/HeaderValsTest") assert msgspec.has_header() assert msgspec.types == ["std_msgs/Header", "int64"] assert msgspec.names == ["header", "data"] assert msgspec.constants == [Constant("int8", "c", 1, "1")] assert msgspec.short_name == "HeaderValsTest" assert msgspec.package == "test_pkg" assert msgspec.full_name == "test_pkg/HeaderValsTest" msgspec = load_msg_from_string(context, "string data\nint64 data2", "test_pkg/ValsTest") assert not msgspec.has_header() assert msgspec.types == ["string", "int64"] assert msgspec.names == ["data", "data2"] assert msgspec.constants == [] assert msgspec.short_name == "ValsTest" assert msgspec.full_name == "test_pkg/ValsTest"
def test_load_msg_from_string(): # make sure Header -> std_msgs/Header conversion works from genmsg.msgs import Constant from genmsg.msg_loader import load_msg_from_string, MsgContext context = MsgContext.create_default() msgspec = load_msg_from_string(context, "Header header", 'test_pkg/HeaderTest') print(msgspec) assert msgspec.has_header() assert msgspec.types == ['std_msgs/Header'] assert msgspec.names == ['header'] assert msgspec.constants == [] assert msgspec.short_name == 'HeaderTest' assert msgspec.package == 'test_pkg' assert msgspec.full_name == 'test_pkg/HeaderTest' msgspec = load_msg_from_string(context, "int8 c=1\nHeader header\nint64 data", 'test_pkg/HeaderValsTest') assert msgspec.has_header() assert msgspec.types == ['std_msgs/Header', 'int64'] assert msgspec.names == ['header', 'data'] assert msgspec.constants == [Constant('int8', 'c', 1, '1')] assert msgspec.short_name == 'HeaderValsTest' assert msgspec.package == 'test_pkg' assert msgspec.full_name == 'test_pkg/HeaderValsTest' msgspec = load_msg_from_string(context, "string data\nint64 data2", 'test_pkg/ValsTest') assert not msgspec.has_header() assert msgspec.types == ['string', 'int64'] assert msgspec.names == ['data', 'data2'] assert msgspec.constants == [] assert msgspec.short_name == 'ValsTest' assert msgspec.full_name == 'test_pkg/ValsTest'
def test__group_fields(): from genfrkl import group_fields from genmsg.msg_loader import load_msg_from_string, MsgContext context = MsgContext.create_default() msg_txt = """ Header header float32 x float64 y int32[5] arr_a uint16 z Float32 xx byte a Byte[3] arr_b """ msgspec = load_msg_from_string(context, msg_txt, 'my_pkg/FieldGroupTest') groups = group_fields(msgspec) assert len(groups) == 7, "Expected 7 groups" assert len(groups[0]) == 1, "First group should have only one element" assert True == groups[6][ 0].is_array, "Last group should have single element, which is an array" assert len(groups[0]) == 1 assert len(groups[1]) == 2 assert len(groups[2]) == 1 assert len(groups[3]) == 1 assert len(groups[4]) == 1 assert len(groups[5]) == 1 assert len(groups[6]) == 1
def _compute_md5_text(msg_context, f): from genmsg import compute_md5_text, load_depends from genmsg.msg_loader import load_msg_from_string text = open(f, 'r').read() short_name = os.path.basename(f)[:-len('.msg')] full_name = "%s/%s"%(TEST_CTX, short_name) spec = load_msg_from_string(msg_context, text, full_name) search_path = get_search_path() load_depends(msg_context, spec, search_path) return compute_md5_text(msg_context, spec)
def _compute_md5_text(msg_context, f): from genmsg import compute_md5_text, load_depends from genmsg.msg_loader import load_msg_from_string text = open(f, 'r').read() short_name = os.path.basename(f)[:-len('.msg')] full_name = "%s/%s" % (TEST_CTX, short_name) spec = load_msg_from_string(msg_context, text, full_name) search_path = get_search_path() load_depends(msg_context, spec, search_path) return compute_md5_text(msg_context, spec)
def test__group_fields4(): from genfrkl import group_fields from genmsg.msg_loader import load_msg_from_string, MsgContext context = MsgContext.create_default() msg_txt = """ """ msgspec = load_msg_from_string(context, msg_txt, 'my_pkg/FieldGroupTest') groups = group_fields(msgspec) assert len(groups) == 0, "Expected 0 groups"
def test_load_msg_from_string_TestString(): from genmsg.msg_loader import load_msg_from_string, MsgContext test_d = get_test_dir() test_ros_dir = os.path.join(test_d, 'test_ros', 'msg') test_string_path = os.path.join(test_ros_dir, 'TestString.msg') with open(test_string_path) as f: text = f.read() msg_context = MsgContext.create_default() _validate_TestString(load_msg_from_string(msg_context, text, 'test_ros/TestString')) # supposed to register assert msg_context.is_registered('test_ros/TestString'), msg_context
def test__group_fields2(): from genfrkl import group_fields from genmsg.msg_loader import load_msg_from_string, MsgContext context = MsgContext.create_default() msg_txt = """ float32 x """ msgspec = load_msg_from_string(context, msg_txt, 'my_pkg/FieldGroupTest') groups = group_fields(msgspec) assert len(groups) == 1, "Expected 1 groups" assert len(groups[0]) == 1, "First group should have only one element"
def test__group_fields5(): from genfrkl import group_fields from genmsg.msg_loader import load_msg_from_string, MsgContext context = MsgContext.create_default() msg_txt = """ uint8 a uint16 b uint32 c uint32[3] d Int64 e """ msgspec = load_msg_from_string(context, msg_txt, 'my_pkg/FieldGroupTest') groups = group_fields(msgspec) assert len(groups) == 3, "Expected 3 groups"
def test__group_fields3(): from genfrkl import group_fields from genmsg.msg_loader import load_msg_from_string, MsgContext context = MsgContext.create_default() msg_txt = """ Float32 x Float32[4] xx float32 z float32 zz """ msgspec = load_msg_from_string(context, msg_txt, 'my_pkg/FieldGroupTest') groups = group_fields(msgspec) assert len(groups) == 3, "Expected 2 groups" assert len(groups[0]) == 1, "First group should have only one element" assert len(groups[1]) == 1, "Second group should have only one element" assert len(groups[2]) == 2, "Third group should have two elements"
def _generate_dynamic_specs(msg_context, specs, dep_msg): """ Dynamically generate message specificition. :param dep_msg: text of dependent .msg definition, ``str`` :returns: type name, message spec, ``str, MsgSpec`` :raises: MsgGenerationException If dep_msg is improperly formatted """ line1 = dep_msg.find('\n') msg_line = dep_msg[:line1] if not msg_line.startswith('MSG: '): raise MsgGenerationException( "invalid input to generate_dynamic: dependent type is missing 'MSG:' type declaration header" ) dep_type = msg_line[5:].strip() dep_pkg, dep_base_type = genmsg.package_resource_name(dep_type) dep_spec = msg_loader.load_msg_from_string(msg_context, dep_msg[line1 + 1:], dep_type) return dep_type, dep_spec
def generate_dynamic(core_type, msg_cat): """ Dymamically generate message classes from msg_cat .msg text gendeps dump. This method modifies sys.path to include a temp file directory. :param core_type str: top-level ROS message type of concatenated .msg text :param msg_cat str: concatenation of full message text (output of gendeps --cat) :raises: MsgGenerationException If dep_msg is improperly formatted """ msg_context = MsgContext.create_default() core_pkg, core_base_type = genmsg.package_resource_name(core_type) # REP 100: pretty gross hack to deal with the fact that we moved # Header. Header is 'special' because it can be used w/o a package # name, so the lookup rules end up failing. We are committed to # never changing std_msgs/Header, so this is generally fine. msg_cat = msg_cat.replace('roslib/Header', 'std_msgs/Header') # separate msg_cat into the core message and dependencies splits = msg_cat.split('\n' + '=' * 80 + '\n') core_msg = splits[0] deps_msgs = splits[1:] # create MsgSpec representations of .msg text specs = { core_type: msg_loader.load_msg_from_string(msg_context, core_msg, core_type) } # - dependencies for dep_msg in deps_msgs: # dependencies require more handling to determine type name dep_type, dep_spec = _generate_dynamic_specs(msg_context, specs, dep_msg) specs[dep_type] = dep_spec # clear the message registration table and register loaded # types. The types have to be registered globally in order for # message generation of dependents to work correctly. msg_context = msg_loader.MsgContext.create_default() search_path = {} # no ability to dynamically load for t, spec in specs.items(): msg_context.register(t, spec) # process actual MsgSpecs: we accumulate them into a single file, # rewriting the generated text as needed buff = StringIO() for t, spec in specs.items(): pkg, s_type = genmsg.package_resource_name(t) # dynamically generate python message code for line in msg_generator(msg_context, spec, search_path): line = _gen_dyn_modify_references(line, t, list(specs.keys())) buff.write(line + '\n') full_text = buff.getvalue() # Create a temporary directory tmp_dir = tempfile.mkdtemp(prefix='genpy_') # Afterwards, we are going to remove the directory so that the .pyc file gets cleaned up if it's still around atexit.register(shutil.rmtree, tmp_dir) # write the entire text to a file and import it (it will get deleted when tmp_dir goes - above) tmp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.py', dir=tmp_dir, delete=False) tmp_file.file.write(full_text) tmp_file.file.close() # import our temporary file as a python module, which requires modifying sys.path sys.path.append(os.path.dirname(tmp_file.name)) # - strip the prefix to turn it into the python module name try: mod = __import__(os.path.basename(tmp_file.name)[:-3]) except Exception: # TODOXXX:REMOVE with open(tmp_file.name) as f: text = f.read() with open('/tmp/foo', 'w') as f2: f2.write(text) raise # finally, retrieve the message classes from the dynamic module messages = {} for t in specs.keys(): pkg, s_type = genmsg.package_resource_name(t) try: messages[t] = getattr(mod, _gen_dyn_name(pkg, s_type)) except AttributeError: raise MsgGenerationException( 'cannot retrieve message class for %s/%s: %s' % (pkg, s_type, _gen_dyn_name(pkg, s_type))) messages[t]._spec = specs[t] return messages