New submission from Andreas H. <ahanga...@gmx.net>:

Currently it is not possible to remove context managers from an ExitStack (or 
AsyncExitStack). 


Workarounds are difficult and generally do accesses implementation details of 
(Async)ExitStack.
See e.g. https://stackoverflow.com/a/37607405. It could be done as follows:


class AsyncExitStackWithPop(contextlib.AsyncExitStack):
    """Same as AsyncExitStack but with pop, i.e. removal functionality"""
    async def pop(self, cm):
        callbacks = self._exit_callbacks
        self._exit_callbacks = collections.deque()
        found = None
        while callbacks:
            cb = callbacks.popleft()
            if cb[1].__self__ == cm:
                found = cb
            else:
                self._exit_callbacks.append(cb)
        if not found:
            raise KeyError("context manager not found")
        if found[0]:
            return found[1](None,None,None)
        else:
            return await found[1](None, None, None)

The alternative is re-implementation of ExitStack with pop functionality, but 
that is also very difficult to get right (especially with exceptions). Which is 
probably the reason why there is ExitStack in the library at all.


So I propose to augment (Async)ExitStack with a `pop` method like above or 
similar to the above.


Use-Cases:

An example is a component that manages several connections to network services. 
During run-time the network services might need to change (i.e. some be 
disconnected and some be connected according to business logic), or handle 
re-connection events (ie. graceful response to network errors).
It is not too hard to imagine more use cases.
Essentially every case where dynamic resource management is needed and where 
single resources are managable with python context managers.

----------
components: Library (Lib)
messages: 401703
nosy: andreash, ncoghlan, yselivanov
priority: normal
severity: normal
status: open
title: Add `pop` function to remove context manager from (Async)ExitStack
type: enhancement
versions: Python 3.10, Python 3.11, Python 3.6, Python 3.7, Python 3.8, Python 
3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue45184>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to