From ed4f83782d9f3404ad600f6131ef78244ff1e162 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Tue, 12 Dec 2023 09:14:13 +0100 Subject: [PATCH] Refs #34305 -- Added SimpleTestCase.enterClassContext() on Python < 3.11. --- django/test/testcases.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/django/test/testcases.py b/django/test/testcases.py index 9855c318be..0e887bdc0b 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -51,6 +51,7 @@ from django.test.utils import ( override_settings, ) from django.utils.functional import classproperty +from django.utils.version import PY311 from django.views.static import serve logger = logging.getLogger("django.test") @@ -64,6 +65,24 @@ __all__ = ( ) +if not PY311: + # Backport of unittest.case._enter_context() from Python 3.11. + def _enter_context(cm, addcleanup): + # Look up the special methods on the type to match the with statement. + cls = type(cm) + try: + enter = cls.__enter__ + exit = cls.__exit__ + except AttributeError: + raise TypeError( + f"'{cls.__module__}.{cls.__qualname__}' object does not support the " + f"context manager protocol" + ) from None + result = enter(cm) + addcleanup(exit, cm, None, None, None) + return result + + def to_list(value): """Put value into a list if it's not already one.""" if not isinstance(value, list): @@ -312,6 +331,12 @@ class SimpleTestCase(unittest.TestCase): """Perform post-test things.""" pass + if not PY311: + # Backport of unittest.TestCase.enterClassContext() from Python 3.11. + @classmethod + def enterClassContext(cls, cm): + return _enter_context(cm, cls.addClassCleanup) + def settings(self, **kwargs): """ A context manager that temporarily sets a setting and reverts to the