[Django] #36942: SimpleTestCase._remove_databases_failures() is not idempotent and crashes on complex MRO.

3 views
Skip to first unread message

Django

unread,
Feb 23, 2026, 5:27:53 PM (5 days ago) Feb 23
to django-...@googlegroups.com
#36942: SimpleTestCase._remove_databases_failures() is not idempotent and crashes
on complex MRO.
---------------------------------------------+-----------------------------
Reporter: Michele0303 | Owner: michele0303
Type: Bug | Status: assigned
Component: Testing framework | Version: 6.0
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 1
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
---------------------------------------------+-----------------------------
When using complex test inheritance (e.g., mixing multiple
LiveServerTestCase subclasses or dynamic test class generation), the
cleanup method
{{{_remove_databases_failures}}} can be called in a state where database
connection methods have already been unwrapped or were never wrapped for a
specific alias.

Currently, the code assumes the wrapped attribute always exists:
{{{setattr(connection, name, method.wrapped)}}}

This leads to an {{{AttributeError: 'function' object has no attribute
'wrapped'.}}}

The proposed fix adds a defensive {{{hasattr(method, "wrapped")}}} check
to make the teardown process idempotent and robust against complex class
hierarchies.
--
Ticket URL: <https://code.djangoproject.com/ticket/36942>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 23, 2026, 5:30:55 PM (5 days ago) Feb 23
to django-...@googlegroups.com
#36942: SimpleTestCase._remove_databases_failures() is not idempotent and crashes
on complex MRO.
-----------------------------------+---------------------------------------
Reporter: Michele Fiori | Owner: michele0303
Type: Bug | Status: assigned
Component: Testing framework | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------------+---------------------------------------
Changes (by Michele Fiori):

* Attachment "check_mro.py" added.

Django

unread,
Feb 23, 2026, 5:49:36 PM (5 days ago) Feb 23
to django-...@googlegroups.com
#36942: SimpleTestCase._remove_databases_failures() is not idempotent and crashes
on complex MRO.
-----------------------------------+---------------------------------------
Reporter: Michele Fiori | Owner: michele0303
Type: Bug | Status: assigned
Component: Testing framework | Version: 6.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------------+---------------------------------------
Description changed by Michele Fiori:

Old description:

> When using complex test inheritance (e.g., mixing multiple
> LiveServerTestCase subclasses or dynamic test class generation), the
> cleanup method
> {{{_remove_databases_failures}}} can be called in a state where database
> connection methods have already been unwrapped or were never wrapped for
> a specific alias.
>
> Currently, the code assumes the wrapped attribute always exists:
> {{{setattr(connection, name, method.wrapped)}}}
>
> This leads to an {{{AttributeError: 'function' object has no attribute
> 'wrapped'.}}}
>
> The proposed fix adds a defensive {{{hasattr(method, "wrapped")}}} check
> to make the teardown process idempotent and robust against complex class
> hierarchies.

New description:

When using complex test inheritance (e.g., mixing multiple
LiveServerTestCase subclasses or dynamic test class generation), the
cleanup method
{{{_remove_databases_failures}}} can be called in a state where database
connection methods have already been unwrapped or were never wrapped for a
specific alias.

Currently, the code assumes the wrapped attribute always exists:
{{{setattr(connection, name, method.wrapped)}}}

This leads to an {{{AttributeError: 'function' object has no attribute
'wrapped'.}}}

The proposed fix adds a defensive {{{hasattr(method, "wrapped")}}} check
to make the teardown process idempotent and robust against complex class
hierarchies.

PR: https://github.com/django/django/pull/20758

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36942#comment:1>

Django

unread,
Feb 26, 2026, 12:01:30 PM (2 days ago) Feb 26
to django-...@googlegroups.com
#36942: SimpleTestCase._remove_databases_failures() is not idempotent and crashes
on complex MRO.
-----------------------------------+---------------------------------------
Reporter: Michele Fiori | Owner: michele0303
Type: Bug | Status: closed
Component: Testing framework | Version: 6.0
Severity: Normal | Resolution: needsinfo
Keywords: | Triage Stage: Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------------+---------------------------------------
Changes (by Jacob Walls):

* needs_tests: 0 => 1
* resolution: => needsinfo
* status: assigned => closed

Comment:

Hi Michele,

Thanks for the report. Seems reasonable, but without a example to play
with it's a little hard to QA it. Could you provide an example class
hierarchy that produces the issue? Happy to take another look then.
--
Ticket URL: <https://code.djangoproject.com/ticket/36942#comment:2>
Reply all
Reply to author
Forward
0 new messages