marrow/package/loader.py
def traverse(obj, target:str, default=nodefault, executable:bool=False, separator:str='.', protect:bool=True):
	"""Traverse down an object, using getattr or getitem.
	
	If ``executable`` is ``True`` any executable function encountered will be, with no arguments. Traversal will
	continue on the result of that call.  You can change the separator as desired, i.e. to a '/'.
	
	By default attributes (but not array elements) prefixed with an underscore are taboo.  They will not resolve,
	raising a LookupError.
	
	Certain allowances are made: if a 'path segment' is numerical, it's treated as an array index. If attribute
	lookup fails, it will re-try on that object using array notation and continue from there.  This makes lookup
	very flexible.
	"""
	
	# TODO: Support numerical slicing, i.e. ``1:4``, or even just ``:-1`` and things.
	assert check_argument_types()
	
	value = obj
	remainder = target
	
	if not target:
		return obj
	
	while separator:
		name, separator, remainder = remainder.partition(separator)
		numeric = name.lstrip('-').isdigit()
		
		try:
			if numeric or (protect and name.startswith('_')):
				raise AttributeError()
			
			value = getattr(value, name)
			
			if executable and callable(value):
				value = value()
		
		except AttributeError:
			try:
				value = value[int(name) if numeric else name]
			
			except (KeyError, TypeError):
				if default is nodefault:
					raise LookupError("Could not resolve '" + target + "' on: " + repr(obj))
				
				return default
		
	return value
def traverse(obj, target:str, default=nodefault, executable:bool=False, separator:str='.', protect:bool=True):
	"""Traverse down an object, using getattr or getitem.
	
	If ``executable`` is ``True`` any executable function encountered will be, with no arguments. Traversal will
	continue on the result of that call.  You can change the separator as desired, i.e. to a '/'.
	
	By default attributes (but not array elements) prefixed with an underscore are taboo.  They will not resolve,
	raising a LookupError.
	
	Certain allowances are made: if a 'path segment' is numerical, it's treated as an array index. If attribute
	lookup fails, it will re-try on that object using array notation and continue from there.  This makes lookup
	very flexible.
	"""
	
	# TODO: Support numerical slicing, i.e. ``1:4``, or even just ``:-1`` and things.
	assert check_argument_types()
	
	value = obj
	remainder = target
	
	if not target:
		return obj
	
	while separator:
		name, separator, remainder = remainder.partition(separator)
		numeric = name.lstrip('-').isdigit()
		
		try:
			if numeric or (protect and name.startswith('_')):
				raise AttributeError()
			
			value = getattr(value, name)
			
			if executable and callable(value):
				value = value()
		
		except AttributeError:
			try:
				value = value[int(name) if numeric else name]
			
			except (KeyError, TypeError):
				if default is nodefault:
					raise LookupError("Could not resolve '" + target + "' on: " + repr(obj))
				
				return default
		
	return value
def traverse ( obj , target : str , default = nodefault , executable : bool = False , separator : str = '.' , protect : bool = True ) : # TODO: Support numerical slicing, i.e. ``1:4``, or even just ``:-1`` and things. assert check_argument_types ( ) value = obj remainder = target if not target : return obj while separator : name , separator , remainder = remainder . partition ( separator ) numeric = name . lstrip ( '-' ) . isdigit ( ) try : if numeric or ( protect and name . startswith ( '_' ) ) : raise AttributeError ( ) value = getattr ( value , name ) if executable and callable ( value ) : value = value ( ) except AttributeError : try : value = value [ int ( name ) if numeric else name ] except ( KeyError , TypeError ) : if default is nodefault : raise LookupError ( "Could not resolve '" + target + "' on: " + repr ( obj ) ) return default return value
Traverse down an object, using getattr or getitem.
	
	If ``executable`` is ``True`` any executable function encountered will be, with no arguments. Traversal will
	continue on the result of that call.  You can change the separator as desired, i.e. to a '/'.
	
	By default attributes (but not array elements) prefixed with an underscore are taboo.  They will not resolve,
	raising a LookupError.
	
	Certain allowances are made: if a 'path segment' is numerical, it's treated as an array index. If attribute
	lookup fails, it will re-try on that object using array notation and continue from there.  This makes lookup
	very flexible.
Traverse down an object using getattr or getitem . If executable is True any executable function encountered will be with no arguments . Traversal will continue on the result of that call . You can change the separator as desired i . e . to a / . By default attributes ( but not array elements ) prefixed with an underscore are taboo . They will not resolve raising a LookupError . Certain allowances are made : if a path segment is numerical it s treated as an array index . If attribute lookup fails it will re - try on that object using array notation and continue from there . This makes lookup very flexible .