Skip to content

Behavioral differences between the with-statement and ExitStack.enter_context #144386

Description

@gottadiveintopython

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)ExitStack does not.

class SlotsCM:
    __slots__ = ("__enter__", "__exit__", )

    def __init__(self):
        self.__enter__ = self.__exit__ = lambda *__: None


# This works
with SlotsCM():
    pass


# This doesn't.
from contextllib import ExitStack
with ExitStack() as stack:
    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

Furthermore, both (async) with-statement and (Async)ExitStack don'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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

3.13bugs and security fixes3.14bugs and security fixes3.15pre-release feature fixes, bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions