def resolve(string, root=None, namespace={}): ''' Resolve an address into a Python object. A more powerful version of `eval`. The main advantage it has over `eval` is that it automatically imports whichever modules are needed to resolve the string. For example: >>> address_tools.resolve('[list, [1, 2], email]') [<type 'list'>, [1, 2], <module 'email' from 'c:\Python27\lib\email\__init__.pyc'>] `root` is an object (usually a module) whose attributes will be looked at when searching for the object. `namespace` is a `dict` whose keys will be searched as well. ''' # Resolving '' to `None`: if string == '': return None # If the string is a simple address, like 'email.encoders', our job is # easy: if _address_pattern.match(string): return get_object_by_address(string, root=root, namespace=namespace) # Getting the true namespace `dict`: (_useless, namespace_dict) = _get_parent_and_dict_from_namespace(namespace) # We're putting items into `our_namespace` instead of using the given # namespace `dict`:... our_namespace = {} our_namespace.update(namespace_dict) # ...because we intend to modify it, and we don't want to be modifying the # user's arguments. # The string that we have is not a plain address, but it may contain plain # addresses. For example, '{email.encoders: 1}' contains an address. We # find all these contained addresses: re_matches = re_tools.searchall(_contained_address_pattern, string) addresses = [re_match.group('address') for re_match in re_matches] # We make sure all the addresses are (1) imported and (2) in # `our_namespace` dict, so we could access them when we `eval` the string: for address in addresses: try: get_object_by_address(address, root=root, namespace=namespace) except Exception: pass else: big_parent_name = address.split('.', 1)[0] big_parent = get_object_by_address(big_parent_name, root=root, namespace=namespace) our_namespace[big_parent_name] = big_parent return eval(string, our_namespace)
def resolve(string, root=None, namespace={}): ''' Resolve an address into a Python object. A more powerful version of `eval`. The main advantage it has over `eval` is that it automatically imports whichever modules are needed to resolve the string. For example: >>> address_tools.resolve('[list, [1, 2], email]') [<class 'list'>, [1, 2], <module 'email' from 'c:\Python31\lib\email\__init__.pyc'>] `root` is an object (usually a module) whose attributes will be looked at when searching for the object. `namespace` is a `dict` whose keys will be searched as well. ''' # Resolving '' to `None`: if string == '': return None # If the string is a simple address, like 'email.encoders', our job is # easy: if _address_pattern.match(string): return get_object_by_address(string, root=root, namespace=namespace) # Getting the true namespace `dict`: (_useless, namespace_dict) = _get_parent_and_dict_from_namespace(namespace) # We're putting items into `our_namespace` instead of using the given # namespace `dict`:... our_namespace = {} our_namespace.update(namespace_dict) # ...because we intend to modify it, and we don't want to be modifying the # user's arguments. # The string that we have is not a plain address, but it may contain plain # addresses. For example, '{email.encoders: 1}' contains an address. We # find all these contained addresses: re_matches = re_tools.searchall(_contained_address_pattern, string) addresses = [re_match.group('address') for re_match in re_matches] # We make sure all the addresses are (1) imported and (2) in # `our_namespace` dict, so we could access them when we `eval` the string: for address in addresses: try: get_object_by_address(address, root=root, namespace=namespace) except Exception: pass else: big_parent_name = address.split('.', 1)[0] big_parent = get_object_by_address(big_parent_name, root=root, namespace=namespace) our_namespace[big_parent_name] = big_parent return eval(string, our_namespace)
def test_searchall(): '''Test the basic workings of `searchall`.''' s = 'asdf df sfg s' result = searchall('(\w+)', s) assert len(result) == 4
def branches(self): ''' ''' re_matches = re_tools.searchall(r'\n[* ] ([^\n]*)', '\n%s' % self._run('branch').std_out) return tuple(re_match.groups()[0] for re_match in re_matches)