python / python/cpython

AttributeError on `with super()`

Open
#129,466 13 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

interpreter-core type-feature
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Bug report

Bug description:

Writing with super() raises an AttributeError. I ran into this implementing context managers inspired by contextlib.contextmnager but which had extra functionality. I can see no reason why with super() should be disallowed, and in fact, super().__enter__() and super().__exit__() work just fine.

Attempting to use an ExitStack as a work around was unsuccessful.

import sys
from contextlib import ExitStack

class Base:
    def __enter__(self):
        print("Entering base context manager")

    def __exit__(self, type, value, traceback):
        print("Exiting base context manager")

def __derived_enter__(self):
    self.context = self.contextlib_style_context()
    next(self.context)
    return self.context

def __derived_exit__(self, type, value, traceback):
    try:
        next(self.context)
    except StopIteration:
        pass

class DerivedUsingEnterExit(Base):
    def contextlib_style_context(self):
        print("Entering contextlib style context manager")
        super().__enter__()
        try:
            yield
        finally:
            super().__exit__(*sys.exc_info())

        print("Exiting contextlib style context manager")

    __enter__ = __derived_enter__
    __exit__ = __derived_exit__

class DerivedUsingWith(Base):
    def contextlib_style_context(self):
        print("Entering contextlib style context manager")
        with super():
            yield

        print("Exiting contextlib style context manager")

    __enter__ = __derived_enter__
    __exit__ = __derived_exit__

class DerivedUsingExitStack(Base):
    def contextlib_style_context(self):
        print("Entering contextlib style context manager")

        with ExitStack() as stack:
            stack.enter_context(super())
            yield

        print("Exiting contextlib style context manager")

    __enter__ = __derived_enter__
    __exit__ = __derived_exit__

# Runs successfully
with DerivedUsingEnterExit() as d:
    pass

# Raises AttributeError
with DerivedUsingWith() as d:
    pass

# Raises AttributeError
with DerivedUsingExitStack() as d:
    pass
CPython versions tested on:

3.13, 3.12

Operating systems tested on:

Windows

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied DerivedUsingWith and DerivedUsingExitStack examples on CPython 3.13 or 3.12, then trace the super() and context-manager entry points involved. Compare them with the working super().enter() and super().exit() case; done means the intended behavior is decided and the reported AttributeError is covered by a regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.