How to remove a context manager from an ExitStack
<p>I have a long-running process called an Updater, that has updates (to an ETL system) submitted to it. The updates have resource requirements that are managed by adding a context manager to the Updater's ExitStack. Some updates will include new configuration, which means that effected resources must be released from the stack and a newly configured version of the resource will be added. I need something like:</p>

<pre><code>with ExitStack() as stack:
    ctx_manager = open("file.txt")
    f = stack.enter_context(ctx_manager)
    ...
    ctx_pop(ctx_manager, stack)  # remove the given context manager from the stack
</code></pre>

<p>Below is an example of something I've gotten to work, but it relies on accessing protected members. I was hoping there might be a less 'dirty' solution than this:</p>

<pre><code>def ctx_pop(cm, stack):
    for item in stack._exit_callbacks:
        if item.__self__ is cm:
            break
    else:
        raise KeyError(repr(cm))
    stack._exit_callbacks.remove(item)
    item(None, None, None)
</code></pre>

<p>Edit: Added known solution</p>