Skip to content

All TestCase classes use a shared stack for class cleanup #99645

Closed

Description

@serhiy-storchaka

TestCase class methods addClassCleanup() and doClassCleanups() are similar to instance methods addCleanup() and doCleanups(). add*Cleanup() add a callback into a list, and do*Cleanups() pop them from a list and call. The main difference is that the latter methods use a list stored as an instance attribute while the former use a list stored as a class attribute.

The problem is that the class attribute TestCase._class_cleanups is shared between all TestCase subclasses. It usually does not cause the problem, because tests in different test classes are run sequentially, but if you run a new test suite while running a test, and the outer test class use addClassCleanup(), the callback registered for the outer test class will be called when cleaning up the inner test class. It can happen when you test unittest itself. It really happened, and was unnoticed only because the outer class did not use addClassCleanup().

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    3.11only security fixes
    3.12only security fixes
    on Nov 21, 2022
  2. added 6 commits that reference this issue on Nov 21, 2022
  3. zware commented on Nov 22, 2022

    @zware
    Member

    Are there existing tests for class cleanups added in various levels of mixins and/or TestCase-derived base classes? I've not gone looking in the hope that you have a quick "yes" answer :)

  4. added a commit that references this issue on Nov 22, 2022
  5. serhiy-storchaka commented on Nov 22, 2022

    @serhiy-storchaka
    MemberAuthor

    AFAIK there are no such tests. But how is this related to this issue?

  6. zware commented on Nov 22, 2022

    @zware
    Member

    Just concerned that this could (though, AFAICT, shouldn't) have an effect on classes that inherit from multiple bases with class-level cleanups. This is a pattern I use frequently, and which came to mind when I saw the change notice.

  7. serhiy-storchaka commented on Nov 22, 2022

    @serhiy-storchaka
    MemberAuthor

    It works in a different way. If you define setUpClass() which calls addClassCleanup() in the base class, and call Base.setUpClass() in setUpClass() of derived classes, Base.setUpClass() will be called multiple times, once for every derived test classes (and for the base class if it is a test class). Correspondingly the cleanup function will be called for every test class. Nothing was changed with this PR.

  8. Repository owner moved this from Todo to Done in Unittest & doctest issueson Nov 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.10 (EOL)end of life3.11only security fixes3.12only security fixestype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions