Search code examples
pythonexitnonetype

Python, __exit__ method should it use return False or no return at all


What's the preferred way and why for __exit__ method when it comes to returning value? Should I write return False or no return at all since that will return None, I think behaviour in both cases will be the same but from what I can see people write it in both ways and I cannot see why.

class File:
    def __init__(self, file_name: str, method: str) -> None:
        self.file_obj = open(file_name, method)
        
    def __enter__(self) -> File:
        return self.file_obj

    def __exit__(self, exctype: Optional[Type[BaseException]], excinst: Optional[BaseException], exctb: Optional[TracebackType]) -> bool:
        self.file_obj.close()
        return False

OR

class File:
    def __init__(self, file_name: str, method: str) -> None:
        self.file_obj = open(file_name, method)
        
    def __enter__(self) -> File:
        return self.file_obj

    def __exit__(self, exctype: Optional[Type[BaseException]], excinst: Optional[BaseException], exctb: Optional[TracebackType]) -> None:
        self.file_obj.close()

Solution

  • As you can read here, definition for contextmanager.__exit__ states:

    "Exit the runtime context and return a Boolean flag indicating if any exception that occurred should be suppressed. (...) Returning a true value from this method will cause the with statement to suppress the exception and continue execution with the statement immediately following the with statement. Otherwise the exception continues propagating after this method has finished executing. Exceptions that occur during execution of this method will replace any exception that occurred in the body of the with statement.

    The exception passed in should never be reraised explicitly - instead, this method should return a false value to indicate that the method completed successfully and does not want to suppress the raised exception. This allows context management code to easily detect whether or not an __exit__() method has actually failed."

    So, if you only return False, it will be functionally the same as no explicit return at all and it is probably redundant. If you decide on adding cases with return True to suppress the exception, it might be helpful to add return False as well for clarity.