Skip to content

Commit

Permalink
Add support for Django 3.0; drop support for Django < 2.2 (django#1389)
Browse files Browse the repository at this point in the history
* Add support for Django 3.0; drop support for Django < 2.2
* Do not call database operations from async code directly

This prevents `SynchronousOnlyOperation` exceptions that were
introduced in Django 3.0.  See
https://docs.djangoproject.com/en/3.0/releases/3.0/#asgi-support
for further details.
  • Loading branch information
michael-k authored and carltongibson committed Dec 11, 2019
1 parent 7b0cc78 commit dd30456
Show file tree
Hide file tree
Showing 9 changed files with 16 additions and 37 deletions.
14 changes: 5 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ dist: xenial
language: python

python:
- "3.8"
- "3.7"
- "3.6"
- "3.5"

env:
- DJANGO="Django==1.11.*"
- DJANGO="Django==2.1.*"
- DJANGO="Django==2.2.*"
- DJANGO="Django~=2.2.8"
- DJANGO="Django==3.0.*"

install:
- pip install -U pip wheel setuptools
Expand All @@ -27,11 +27,7 @@ stages:

jobs:
include:
- python: "3.7"
env: DJANGO="Django==2.1.*"
- python: "3.7"
env: DJANGO="Django==2.2.*"
- python: "3.8"
- python: "3.5"
env: DJANGO="Django==2.2.*"

- stage: lint
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Dependencies
------------

All Channels projects currently support Python 3.5 and up. ``channels`` is
compatible with Django 1.11, 2.1, and 2.2.
compatible with Django 2.2 and 3.0.


Contributing
Expand Down
10 changes: 0 additions & 10 deletions channels/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,6 @@ def load_middleware(self):
)
self._exception_middleware = self.__class__._exception_middleware

# Support additional arguments for Django 1.11 and 2.0.
if hasattr(self.__class__, "_request_middleware"):
self._request_middleware = self.__class__._request_middleware
self._response_middleware = self.__class__._response_middleware

else:
super(AsgiHandler, self).load_middleware()
self.__class__._middleware_chain = self._middleware_chain
Expand All @@ -298,11 +293,6 @@ def load_middleware(self):
)
self.__class__._exception_middleware = self._exception_middleware

# Support additional arguments for Django 1.11 and 2.0.
if hasattr(self, "_request_middleware"):
self.__class__._request_middleware = self._request_middleware
self.__class__._response_middleware = self._response_middleware

@classmethod
def encode_response(cls, response):
"""
Expand Down
6 changes: 1 addition & 5 deletions channels/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.urls.exceptions import Resolver404
from django.urls.resolvers import URLResolver

from channels.http import AsgiHandler

try:
from django.urls.resolvers import URLResolver
except ImportError: # Django 1.11
from django.urls import RegexURLResolver as URLResolver


"""
All Routing instances inside this file are also valid ASGI applications - with
Expand Down
2 changes: 1 addition & 1 deletion channels/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ async def send(self, message):
and message.get("status", 200) != 500
and (modified or settings.SESSION_SAVE_EVERY_REQUEST)
):
self.save_session()
await database_sync_to_async(self.save_session)()
# If this is a message type that can transport cookies back to the
# client, then do so.
if message["type"] in self.middleware.cookie_response_message_types:
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
url='http://github.com/django/channels',
author='Django Software Foundation',
author_email='[email protected]',
description="Brings async, event-driven capabilities to Django. Django 1.11 and up only.",
description="Brings async, event-driven capabilities to Django. Django 2.2 and up only.",
license='BSD',
packages=find_packages(exclude=['tests']),
include_package_data=True,
python_requires='>=3.5',
install_requires=[
'Django>=1.11',
'Django>=2.2',
'asgiref~=3.2',
'daphne~=2.3',
],
Expand Down
3 changes: 2 additions & 1 deletion tests/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from asgiref.testing import ApplicationCommunicator
from channels.consumer import AsyncConsumer
from channels.db import database_sync_to_async
from channels.http import AsgiHandler, AsgiRequest
from channels.sessions import SessionMiddlewareStack
from channels.testing import HttpCommunicator
Expand Down Expand Up @@ -335,7 +336,7 @@ class SimpleHttpApp(AsyncConsumer):
"""

async def http_request(self, event):
self.scope["session"].save()
await database_sync_to_async(self.scope["session"].save)()
assert self.scope["path"] == "/test/"
assert self.scope["method"] == "GET"
await self.send(
Expand Down
5 changes: 1 addition & 4 deletions tests/test_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,7 @@ def test_invalid_routes():
"""
Test URLRouter route validation
"""
try:
from django.urls import include
except ImportError: # Django 1.11
from django.conf.urls import include
from django.urls import include

with pytest.raises(ImproperlyConfigured) as exc:
URLRouter([url(r"^$", include([]))])
Expand Down
7 changes: 3 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py{36,37,38}-dj{11,21,22,master}
envlist = py{36,37,38}-dj{22,30,master}

[testenv]
usedevelop = true
Expand All @@ -10,9 +10,8 @@ commands =
py.test -v {posargs}

deps =
dj11: Django==1.11.*
dj21: Django==2.1.*
dj22: Django==2.2.*
dj22: Django~=2.2.8
dj30: Django==3.0.*
djmaster: https://github.com/django/django/archive/master.tar.gz

[testenv:qa]
Expand Down

0 comments on commit dd30456

Please sign in to comment.