You have the following:
@contextmanager def versioned(file_path, mode):
Your main problem, of course, is that you yield from the context manager exits the with statement via as , but is not the object returned by your function. You need a function that returns what behaves as an open() object. That is, the object of the context manager, which gives itself.
Whatever you can do, it depends on what you can do with the versioned_file type. If you cannot change this, you are mostly out of luck. If you can change it, you need to implement the __enter__ and __exit__ functions, as described in PEP 343 .
In your code example, however, it already has it, and your break code is the same as it is when you exit the context. So don't worry about contextlib, just return the result of open() .
For other examples where you need __enter__ and __exit__ , if you like the contextlib style (and who doesn't?), You can combine two things. Write a context function that is decorated by @contextmanager and gives self . Then do:
def __enter__(self): self.context = context()
It mostly depends on whether you find it better or worse than splitting the installation code into __enter__ and the break code into __exit__ . I usually find it better.
source share