Context manager protocol extension

Okay, it seems before answering the question “how to express rebinding after block” we first need to answer “do we want the protocol allow rebinding at all”. This is a pretty important question, because unlike depth thing it is something the language does not allow to do in a clear way.

To give context to new readers, the problem was first raised here

In code it looks like

from time import perf_counter
class TimeIt:
    def __init__(self):
        self.elapsed = None

    def __enter__(self):
        self.start_time = perf_counter()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.elapsed = perf_counter() - self.start_time

with TimeIt() as time_it:
    ...
print(time_it.elapsed)

# In case manager.__enter__ returns non-self
with (use_me_to_get_result := cm()) as enter:
     ...  # work with 'enter'
use_me_to_get_result.result

The proposed solution is to allow to return extra value (return value of __leave__ or second yielded value of __with__). When such value is present as target of with statement rebinds with that value.

I’d like to hear input from all the people, whenever this “rebind after block” feature is desirable. Maybe things like timeit and assertRaises are black sheeps, rare cases that should use workarounds.