forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Python
		
	
	
	
# ====================================================================
 | 
						|
# Provides a with-style resource handler for optionally-None resources
 | 
						|
# ====================================================================
 | 
						|
 | 
						|
 | 
						|
class optional_with(object):
 | 
						|
    # pylint: disable=too-few-public-methods
 | 
						|
    # This is a wrapper - it is not meant to provide any extra methods.
 | 
						|
    """Provides a wrapper for objects supporting "with", allowing None.
 | 
						|
 | 
						|
    This lets a user use the "with object" syntax for resource usage
 | 
						|
    (e.g. locks) even when the wrapped with object is None.
 | 
						|
 | 
						|
    e.g.
 | 
						|
 | 
						|
    wrapped_lock = optional_with(thread.Lock())
 | 
						|
    with wrapped_lock:
 | 
						|
        # Do something while the lock is obtained.
 | 
						|
        pass
 | 
						|
 | 
						|
    might_be_none = None
 | 
						|
    wrapped_none = optional_with(might_be_none)
 | 
						|
    with wrapped_none:
 | 
						|
        # This code here still works.
 | 
						|
        pass
 | 
						|
 | 
						|
    This prevents having to write code like this when
 | 
						|
    a lock is optional:
 | 
						|
 | 
						|
    if lock:
 | 
						|
        lock.acquire()
 | 
						|
 | 
						|
    try:
 | 
						|
        code_fragment_always_run()
 | 
						|
    finally:
 | 
						|
        if lock:
 | 
						|
            lock.release()
 | 
						|
 | 
						|
    And I'd posit it is safer, as it becomes impossible to
 | 
						|
    forget the try/finally using optional_with(), since
 | 
						|
    the with syntax can be used.
 | 
						|
    """
 | 
						|
 | 
						|
    def __init__(self, wrapped_object):
 | 
						|
        self.wrapped_object = wrapped_object
 | 
						|
 | 
						|
    def __enter__(self):
 | 
						|
        if self.wrapped_object is not None:
 | 
						|
            return self.wrapped_object.__enter__()
 | 
						|
        else:
 | 
						|
            return self
 | 
						|
 | 
						|
    def __exit__(self, the_type, value, traceback):
 | 
						|
        if self.wrapped_object is not None:
 | 
						|
            return self.wrapped_object.__exit__(the_type, value, traceback)
 | 
						|
        else:
 | 
						|
            # Don't suppress any exceptions
 | 
						|
            return False
 |