Received: from mail.netlandish.com (mail.netlandish.com [174.136.98.166])
	by code.netlandish.com (Postfix) with ESMTP id D748F81537
	for <~petersanchez/public-inbox@lists.code.netlandish.com>; Tue, 25 Apr 2023 08:44:28 +0000 (UTC)
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=209.85.221.44; helo=mail-wr1-f44.google.com; envelope-from=hugo@yunojuno.com; receiver=<UNKNOWN> 
Authentication-Results: mail.netlandish.com;
	dkim=pass (2048-bit key; unprotected) header.d=yunojuno-com.20221208.gappssmtp.com header.i=@yunojuno-com.20221208.gappssmtp.com header.b=Bxw3KH+W
Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44])
	by mail.netlandish.com (Postfix) with ESMTP id 04A30152FC8
	for <~petersanchez/public-inbox@lists.code.netlandish.com>; Tue, 25 Apr 2023 08:44:26 +0000 (UTC)
Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-2f625d52275so5215089f8f.3
        for <~petersanchez/public-inbox@lists.code.netlandish.com>; Tue, 25 Apr 2023 01:44:26 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=yunojuno-com.20221208.gappssmtp.com; s=20221208; t=1682412265; x=1685004265;
        h=to:from:date:user-agent:message-id:subject
         :content-transfer-encoding:mime-version:from:to:cc:subject:date
         :message-id:reply-to;
        bh=sFYfEDjrj9ZD9bigLIMNSieupOEXwcx2mOHUT3n21ag=;
        b=Bxw3KH+WWmRRDlT1JAD1tdZq/Kfbqo91b1C6oiyAIfE8wNP8jQ30K9FgHzRtpy/in0
         l0MJIy6Z8NVxfWuMzLmka+RrUVGpO6owHEHgIWr6ed8lZ3aWBLmcL/xSvEDWpZ5KpyQ5
         IfX7UkD0fN81j0eSGVunf6zaGZto7Cf7/jDCNtXo/2UzdxjxKW5PD4tKAe9hF7IX5csb
         /wvRp90DSy35HnsZamrOVv9Q3NbnszQSAEcRXFr4O87TUu6L5ua0Fb2JSlcrh8IYa/ek
         6j/tJmOoJ3kf69pCgo+Csiv9EGckSIze8PyOgKp66gmmEiJlUDEjrxU+sjPzcV9fN5/q
         fa4w==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20221208; t=1682412265; x=1685004265;
        h=to:from:date:user-agent:message-id:subject
         :content-transfer-encoding:mime-version:x-gm-message-state:from:to
         :cc:subject:date:message-id:reply-to;
        bh=sFYfEDjrj9ZD9bigLIMNSieupOEXwcx2mOHUT3n21ag=;
        b=POv2wwmqCSbny02iMAFNz3d06t148jFYPW2G6SuiGh8URo4zYnY4KLBpC/2JyhHgih
         y5xE+gaNlLrJdW7dKy7AiiEoNKL8ThM4yuNael+kWGIYmecLEwpZsA+BAPXbtwedVoLk
         D7W/ulpJZP+Yik7vNF8RONM+3hgr9dT6lfZ4S+J/3Xfw+9eUrK2rS/xZjL/18zkR+Dh3
         dvzVUf/hbzlMwYkRGWUpmklIwZcPP7xbnKB8/3+I7Bx4GBHWINu+c+SNOFX3g7FYuBC2
         /ARdfykJtgj4JkDISY4vI3R6JE6EkyduJb5sIAeo5zNeb266j0r6KWbGzpqGwWFsIT9v
         jO2w==
X-Gm-Message-State: AAQBX9dm7AFU0TeIEn70G//BKUUdRZYi/Vm+CoZNPKKlIZTvSkBc4Udx
	bFlPC6xxAApI7NfIw4nzux24QI0o1Wgu2yBJccVY9A==
X-Google-Smtp-Source: AKy350bLxWpJrXDrz/Jgw6zib4bUIFgm88sXq7qQ9IV9/j2h0QePgcIREvZHbUgSwiYKMODwmcZjzw==
X-Received: by 2002:a5d:58cd:0:b0:304:4031:acb0 with SMTP id o13-20020a5d58cd000000b003044031acb0mr8445569wrf.52.1682412264629;
        Tue, 25 Apr 2023 01:44:24 -0700 (PDT)
Received: from [127.0.0.1] ([104.28.231.254])
        by smtp.gmail.com with ESMTPSA id r6-20020a05600c458600b003f195d540d9sm9890469wmo.14.2023.04.25.01.44.24
        for <~petersanchez/public-inbox@lists.code.netlandish.com>
        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
        Tue, 25 Apr 2023 01:44:24 -0700 (PDT)
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Subject: [PATCH django-impersonate] Add support for Django 5.0 (pre)
X-Mercurial-Node: 4a152ad24364e0778c555ec62a8dd3aaef5eebaa
X-Mercurial-Series-Index: 1
X-Mercurial-Series-Total: 1
Message-Id: <4a152ad24364e0778c55.1682412263@C17FQ18CQ6L4>
X-Mercurial-Series-Id: <4a152ad24364e0778c55.1682412263@C17FQ18CQ6L4>
User-Agent: Mercurial-patchbomb/6.4rc0
Date: Tue, 25 Apr 2023 09:44:23 +0100
From: =?iso-8859-1?q?Hugo_Rodger-Brown?= <hugo@yunojuno.com>
To: ~petersanchez/public-inbox@lists.code.netlandish.com

# HG changeset patch
# User Hugo Rodger-Brown
# Date 1681222628 -3600
#      Tue Apr 11 15:17:08 2023 +0100
# Node ID 4a152ad24364e0778c555ec62a8dd3aaef5eebaa
# Parent  76e93d43501e5304d6b27e7f7072e4d8aab15104
Add support for Django 5.0 (pre)

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -1,15 +1,16 @@
 syntax:glob
+.*.swp
 .coverage
+.DS_Store
+.idea
 .tox
-settings_local.py
-.*.swp
+.venv
+*.diff
+*.komodoproject
 **.pyc
 MANIFEST
-.idea
+settings_local.py
 
 syntax:regexp
 ^htmlcov$
 ^env$
-syntax: glob
-*.komodoproject
-.DS_Store
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
-include BSD-LICENSE
+include LICENSE
 include CHANGELOG
 include README.rst
 recursive-include impersonate/templates *
diff --git a/impersonate/admin.py b/impersonate/admin.py
--- a/impersonate/admin.py
+++ b/impersonate/admin.py
@@ -5,15 +5,11 @@
 from django.db.utils import NotSupportedError
 from django.utils.html import format_html
 
+from .compat import reverse
 from .helpers import User, check_allow_impersonate
 from .models import ImpersonationLog
 from .settings import settings
 
-try:
-    from django.urls import reverse
-except ImportError:
-    from django.core.urlresolvers import reverse
-
 logger = logging.getLogger(__name__)
 
 
diff --git a/impersonate/compat/__init__.py b/impersonate/compat/__init__.py
new file mode 100644
--- /dev/null
+++ b/impersonate/compat/__init__.py
@@ -0,0 +1,4 @@
+try:
+    from django.urls import reverse
+except ImportError:
+    from django.core.urlresolvers import reverse
diff --git a/impersonate/compat/timezone.py b/impersonate/compat/timezone.py
new file mode 100644
--- /dev/null
+++ b/impersonate/compat/timezone.py
@@ -0,0 +1,6 @@
+# timezone.utc removed in Django 5
+try:
+    from django.utils.timezone import utc
+except ImportError:
+    from zoneinfo import ZoneInfo
+    utc = ZoneInfo("UTC")
diff --git a/impersonate/middleware.py b/impersonate/middleware.py
--- a/impersonate/middleware.py
+++ b/impersonate/middleware.py
@@ -2,11 +2,11 @@
 from datetime import datetime, timedelta
 
 from django.http import HttpResponseNotAllowed
-from django.shortcuts import redirect, reverse
-from django.utils import timezone
+from django.shortcuts import redirect
 from django.utils.deprecation import MiddlewareMixin
 from django.utils.functional import SimpleLazyObject
 
+from .compat import reverse, timezone
 from .helpers import User, check_allow_for_uri, check_allow_for_user, check_read_only
 from .settings import settings
 
diff --git a/impersonate/tests.py b/impersonate/tests.py
--- a/impersonate/tests.py
+++ b/impersonate/tests.py
@@ -19,7 +19,7 @@
         is_superuser = False
         is_staff = False
 '''
-from datetime import datetime, timedelta, timezone
+from datetime import datetime, timedelta
 from distutils.version import LooseVersion
 from unittest.mock import PropertyMock, patch
 from urllib.parse import urlencode, urlsplit
@@ -35,17 +35,15 @@
 from django.utils.duration import duration_string
 
 from .admin import (
-    ImpersonationLogAdmin, ImpersonatorFilter, SessionStateFilter,
+    ImpersonationLogAdmin,
+    ImpersonatorFilter,
+    SessionStateFilter,
 )
+from .compat import reverse, timezone
 from .helpers import users_impersonable
 from .models import ImpersonationLog
 from .signals import session_begin, session_end
 
-try:
-    from django.urls import reverse
-except ImportError:
-    from django.core.urlresolvers import reverse
-
 User = get_user_model()
 django_version_loose = LooseVersion(django.get_version())
 
diff --git a/impersonate/views.py b/impersonate/views.py
--- a/impersonate/views.py
+++ b/impersonate/views.py
@@ -5,12 +5,16 @@
 from django.db.models import Q
 from django.http import Http404
 from django.shortcuts import get_object_or_404, redirect, render
-from django.utils import timezone
 
+from .compat import timezone
 from .decorators import allowed_user_required
 from .helpers import (
-    check_allow_for_user, get_paginator, get_redir_arg, get_redir_field,
-    get_redir_path, users_impersonable,
+    check_allow_for_user,
+    get_paginator,
+    get_redir_arg,
+    get_redir_field,
+    get_redir_path,
+    users_impersonable,
 )
 from .settings import User, settings
 from .signals import session_begin, session_end
diff --git a/pyproject.toml b/pyproject.toml
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,7 @@
 [tool.black]
 line-length = 79
 skip-string-normalization = true
-target-version = ['py37', 'py38']
+target-version = ['py37', 'py38', 'py39', 'py310', 'py311']
 include = '\.pyi?$'
 exclude = '''
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -48,11 +48,14 @@
         'Framework :: Django :: 2.2',
         'Framework :: Django :: 3.2',
         'Framework :: Django :: 4.0',
+        'Framework :: Django :: 4.1',
+        'Framework :: Django :: 4.2',
         'Programming Language :: Python',
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
         'Programming Language :: Python :: 3.10',
+        'Programming Language :: Python :: 3.11',
         'Environment :: Web Environment',
     ],
 )
diff --git a/tox.ini b/tox.ini
--- a/tox.ini
+++ b/tox.ini
@@ -1,10 +1,19 @@
 [tox]
 downloadcache = {toxworkdir}/cache/
-envlist = py{37,38,39}-django{2.2,3.2},py{38,39}-django{4.0},py310-django{3.2,4.0}
+envlist =
+	py{37,38,39}-django{2.2,3.0,3.1,3.2}
+	py{38,39,310}-django{4.0}
+	py{38,39,310,311}-django{4.1}
+	py{310,311}-django{main}
 
 [testenv]
 commands = {envpython} runtests.py
 deps =
 	django2.2: django>=2.2,<3.0
+	django3.0: django>=3.0,<3.1
+	django3.1: django>=3.1,<3.2
 	django3.2: django>=3.2,<4.0
 	django4.0: django>=4.0,<4.1
+	django4.1: django>=4.1,<4.2
+	django4.2: django>=4.2,<4.3
+	djangomain: https://github.com/django/django/archive/main.tar.g