1

I'm trying to write a context manager with contextlib.contextmanager. The following works as expected:

from pathlib import Path
from contextlib import contextmanager

@contextmanager
def Dir(path):
    path = Path(path).expanduser().resolve()
    try:
        path.mkdir(parents=True, exist_ok=True)
        yield path
    except PermissionError as err:
        print(err)
        raise err

However if I want it to log and suppress the exception by removing the raise err line, I get the following error:

/usr/lib64/python3.7/contextlib.py in __enter__(self)
    112             return next(self.gen)
    113         except StopIteration:
--> 114             raise RuntimeError("generator didn't yield") from None
    115 
    116     def __exit__(self, type, value, traceback):

RuntimeError: generator didn't yield

What am I missing?

PS: I am aware of this old question, but it does not resolve my issue.

suvayu
  • 4,271
  • 2
  • 29
  • 35
  • When you write `with Dir("foo") as path:`, and there is an error, what would `path` be? There is no way for a `contextmanager` to not run its function, except by throwing an exception. If you suppress the exception, you have to `yield`. – Amadan May 31 '19 at 10:12
  • When there's an error, the code block shouldn't run. `yield`ing again leads to an `None` being passed on to the code block, which is worse! When there's an error, I just want to log instead of raising an exception. I'll add an example in my question to show what I am expecting. – suvayu May 31 '19 at 10:16
  • I know what you're expecting. But I will repeat myself: There is no way for a `contextmanager` to not run its function, except by throwing an exception. What you want is, AFAIK, not possible in Python. `if` is there for conditional execution; `try` is there to handle exceptional cases; `with` is there to execute something with a resource. You can't abuse `with` as a conditional, or error recovery. – Amadan May 31 '19 at 10:18
  • See [this answer](https://stackoverflow.com/a/6090497/240443) for the closest alternative. – Amadan May 31 '19 at 10:25
  • @Amadan Okay, I see what you mean. I'll reconsider my approach. And thanks for the link – suvayu May 31 '19 at 10:26

0 Answers0