python / python/cpython

`atexit` module breaks refleak check

Open
#139,289 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

extension-modules tests type-bug
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

Bug report

Bug description:

If the test registers a callback with atexit module, refleak test will consider it a leak.

    def test_refleak(self):
        atexit.register(lambda: None)

This is the root cause of the buildbot failure of https://github.com/python/cpython/pull/139185. It's a couple of coincidences that caused the seemingly unrelated issue. Basically, clearing the module cache in test_zipimport made the module-level code in rlcompleter, which includes a register to atexit, run more than once.

There are a few possible approaches to fix this, but I did not find the solution that I'm immediately happy with.

I consider this a test framework bug as this should be a valid behavior. The ideal solution is to keep the atexit callbacks before running test in a loop and restore it after. However, atexit does not provide such an interface, public or private. You can either clear it or run it. The callbacks are stored in a state of the interpreter and we don't have any access to it.

Without that, we either need to somehow calculate the allocated memory by atexit, or hope that no one writes a test that writes to atexit. Of course there might be other ways that I did not think of.

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs
  • gh-139305
  • gh-139357
  • [3.14] gh-139305 was backported as part of gh-139280

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 with the refleak test framework and the test_refleak example that registers an atexit callback. Inspect how test_zipimport clearing the module cache causes rlcompleter's module-level registration to run repeatedly, and review linked PRs gh-139305 and gh-139357 for existing work. Done means valid atexit registrations no longer appear as refleaks.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.