def test_is_global(): from rosgraph.names import is_global try: is_global(None) assert False, "is_global should raise exception on invalid param" except: pass tests = ['/', '/global', '/global2'] for t in tests: assert is_global(t) fails = ['', 'not_global', 'not/global'] for t in fails: assert not is_global(t)
def validator(param_value, caller_id): if not param_value or not isstring(param_value): raise ParameterInvalid("ERROR: parameter [%s] must be a non-empty string"%param_name) #TODO: actual validation of chars if not is_global(param_value): raise ParameterInvalid("ERROR: parameter [%s] must be a globally referenced name"%param_name) return param_value
def scoped_name(caller_id, name): """ Convert the global caller_id to a relative name within the namespace. For example, for namespace '/foo' and name '/foo/bar/name', the return value will be 'bar/name' WARNING: scoped_name does not validate that name is actually within the supplied namespace. @param caller_id: caller ID, in canonical form @type caller_id: str @param name: name to scope @type name: str @return: name scoped to the caller_id's namespace. @rtype: str """ if not is_global(caller_id): raise ROSException("caller_id must be global") return canonicalize_name(name)[len(namespace(caller_id)):]
def search_param(self, ns, key): """ Search for matching parameter key for search param key. Search for key starts at ns and proceeds upwards to the root. As such, search_param should only be called with a relative parameter name. search_param's behavior is to search for the first partial match. For example, imagine that there are two 'robot_description' parameters: - /robot_description - /robot_description/arm - /robot_description/base - /pr2/robot_description - /pr2/robot_description/base If I start in the namespace /pr2/foo and search for 'robot_description', search_param will match /pr2/robot_description. If I search for 'robot_description/arm' it will return /pr2/robot_description/arm, even though that parameter does not exist (yet). @param ns: namespace to begin search from. @type ns: str @param key: Parameter key. @type key: str @return: key of matching parameter or None if no matching parameter. @rtype: str """ if not key or is_private(key): raise ValueError("invalid key") if not is_global(ns): raise ValueError("namespace must be global") if is_global(key): if self.has_param(key): return key else: return None # there are more efficient implementations, but our hiearchy # is not very deep and this is fairly clean code to read. # - we only search for the first namespace in the key to check for a match key_namespaces = [x for x in key.split(SEP) if x] key_ns = key_namespaces[0] # - corner case: have to test initial namespace first as # negative indices won't work with 0 search_key = ns_join(ns, key_ns) if self.has_param(search_key): # resolve to full key return ns_join(ns, key) namespaces = [x for x in ns.split(SEP) if x] for i in xrange(1, len(namespaces)+1): search_key = SEP + SEP.join(namespaces[0:-i] + [key_ns]) if self.has_param(search_key): # we have a match on the namespace of the key, so # compose the full key and return it full_key = SEP + SEP.join(namespaces[0:-i] + [key]) return full_key return None