classSlotsCM:
__slots__= ("__enter__", "__exit__", )
def__init__(self):
self.__enter__=self.__exit__=lambda*__: None# This workswithSlotsCM():
pass# This doesn't.fromcontextllibimportExitStackwithExitStack() asstack:
stack.enter_context(SlotsCM())Traceback (most recent call last):
File "xxxx.py", line 16, in <module>
stack.enter_context(SlotsCM())
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
File "......../contextlib.py", line 530, in enter_context
result = _enter(cm)
TypeError: 'member_descriptor' object is not callable
Bug report
Bug description:
I noticed a behavioral difference between the (async) with statement and
(Async)ExitStack. The with statement correctly recognizes context manager methods (__enter__,__exit__,__aenter__, and__aexit__) even when they are defined via__slots__, whereas(Async)ExitStackdoes not.Furthermore, both (async) with-statement and
(Async)ExitStackdon't suppot those special dunder methods stored in__dict__. You can verify from this repository:https://github.com/gottadiveintopython/invest-context-manager
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs