Skip to content

Commit 2a600b0

Browse files
committed
unitest enterClassContext compatibility shim for python<3.11/django<5.1
1 parent ea19bec commit 2a600b0

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

channels/testing/live.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
11
import threading
22
from functools import partial
33

4+
import django
45
from django.contrib.staticfiles.handlers import ASGIStaticFilesHandler
56
from django.db import connections
67
from django.db.backends.base.creation import TEST_DATABASE_PREFIX
78
from django.test.testcases import TransactionTestCase
89
from django.test.utils import modify_settings
910
from django.utils.functional import classproperty
11+
from django.utils.version import PY311
1012

1113
from channels.routing import get_default_application
1214

15+
if not PY311:
16+
# Backport of unittest.case._enter_context() from Python 3.11.
17+
def _enter_context(cm, addcleanup):
18+
# Look up the special methods on the type to match the with statement.
19+
cls = type(cm)
20+
try:
21+
enter = cls.__enter__
22+
exit = cls.__exit__
23+
except AttributeError:
24+
raise TypeError(
25+
f"'{cls.__module__}.{cls.__qualname__}' object does not support the "
26+
f"context manager protocol"
27+
) from None
28+
result = enter(cm)
29+
addcleanup(exit, cm, None, None, None)
30+
return result
31+
1332

1433
def make_application(*, static_wrapper):
1534
# Module-level function for pickle-ability
@@ -124,6 +143,12 @@ class ChannelsLiveServerTestCase(TransactionTestCase):
124143
static_handler = ASGIStaticFilesHandler
125144
serve_static = True
126145

146+
if not PY311:
147+
# Backport of unittest.TestCase.enterClassContext() from Python 3.11.
148+
@classmethod
149+
def enterClassContext(cls, cm):
150+
return _enter_context(cm, cls.addClassCleanup)
151+
127152
@classproperty
128153
def live_server_url(cls):
129154
return "http://%s:%s" % (cls.host, cls.server_thread.port)
@@ -193,11 +218,6 @@ def _terminate_thread(cls):
193218
for conn in cls.server_thread.connections_override.values():
194219
conn.dec_thread_sharing()
195220

196-
@classmethod
197-
def tearDownClass(cls):
198-
# The cleanup is now handled by addClassCleanup in _start_server_thread
199-
super().tearDownClass()
200-
201221
@classmethod
202222
def _is_in_memory_db(cls, connection):
203223
"""

0 commit comments

Comments
 (0)