I am trying to find a good way to explain why creating an specialized context manager by calling another one works as expected. I am not complaining!, it is great that it does. But I was not sure if that it would work until I tested it and therefore I feel I am loosing something.
Just to clarify considere the following example:
>>> from contextlib import contextmanager
>>> @contextmanager
... def f(val):
... print(val)
... yield
... print(val+1)
...
>>>
>>> with f(1):
... print(3)
...
1
3
2
And now we specialize it:
>>> def f42():
... return f(42)
...
>>> with f42():
... print(3)
...
42
3
43
I guess what is confusing me is why does the yield from f bubbles up through f42? Why I do not need to write f42 as a context manager explicitly.