Skip to content

Unittest class instances no longer released on test teardown since pytest 8.2.0 #12367

@bluetech

Description

@bluetech

Follow up to #12266. Related to #12198.

Since 0dc0360 in pytest 8.2, pytest started holding onto class instances on the Function items, where previously the instance was gone on teardown.

I was a bit confused how the previous behavior happened, since it doesn't happen for non-unittest test classes. The secret is this line:

https://github.com/pytest-dev/pytest/blob/889d9b28d786c75b66f4d1acb80123bdb341639c/src/_pytest/unittest.py#L225C9-L225C25

turns out unittest explicitly clears up the obj on teardown, since e46e653 (pytest 3.0.4). The reason this regressed in 0dc0360 is that we now also need to clear _instance. So the fix is simple.

Commit 0dc0360 came with a test, but it didn't catch the regression. I will try to improve it.


One obvious question I think is, why do we only clear _obj for TestCaseFunction and not for Function itself (superclass of TestCaseFunction used for regular test methods and functions)? As far as I can see there is no good reason, we should do it and gain the same "prompt release" behavior for all tests. All of pytest's tests pass when I try it.

Unfortunately there is a hitch involving plugins. The Function item has a feature where it can take a callobj argument to use as the obj instead of getting it itself. In this case the Function doesn't "own" the obj and can't clear it, otherwise when the item is re-run (as is done by plugins such as pytest-rerunfailures) the obj will not be the callobj on the second run.

Internally, callobj is only used for FunctionDefinition and it's not a problem to handle this, but callobj is also used by several plugins, most notably pytest-asyncio and we can't break that.

So while it will be good to do this change more generally, it requires care. So for now I'll only do the fix for unittest.

Metadata

Metadata

Assignees

Labels

plugin: unittestrelated to the unittest integration builtin plugintype: regressionindicates a problem that was introduced in a release which was working previously

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions