Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-django-tastypie for 
openSUSE:Factory checked in at 2022-02-26 17:02:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-tastypie (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-tastypie.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-tastypie"

Sat Feb 26 17:02:12 2022 rev:17 rq:957670 version:0.14.4

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-tastypie/python-django-tastypie.changes
    2021-06-09 21:53:14.706575593 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-django-tastypie.new.1958/python-django-tastypie.changes
  2022-02-26 17:02:43.859542078 +0100
@@ -1,0 +2,8 @@
+Fri Feb 25 21:59:18 UTC 2022 - Matej Cepl <mc...@suse.com>
+
+- Update to 0.14.4:
+  - Django 4.0 support
+- Fix testing of the package.
+- Remove upstreamed patch merged_pr_1624_chunk.patch
+
+-------------------------------------------------------------------

Old:
----
  merged_pr_1624_chunk.patch
  v0.14.3.tar.gz

New:
----
  v0.14.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-django-tastypie.spec ++++++
--- /var/tmp/diff_new_pack.PQac9b/_old  2022-02-26 17:02:44.351542156 +0100
+++ /var/tmp/diff_new_pack.PQac9b/_new  2022-02-26 17:02:44.359542158 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-django-tastypie
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,14 +18,12 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-django-tastypie
-Version:        0.14.3
+Version:        0.14.4
 Release:        0
 Summary:        A webservice API framework layer for Django
 License:        BSD-3-Clause
 URL:            https://github.com/django-tastypie/django-tastypie
 Source:         
https://github.com/django-tastypie/django-tastypie/archive/v%{version}.tar.gz
-# PATCH-FIX-UPSTREAM merged_pr_1624_chunk.patch -- based on PR 1624
-Patch0:         merged_pr_1624_chunk.patch
 BuildRequires:  %{python_module Django >= 1.11.0}
 BuildRequires:  %{python_module PyYAML}
 BuildRequires:  %{python_module biplist}
@@ -53,7 +51,8 @@
 
 %prep
 %setup -q -n django-tastypie-%{version}
-%patch0 -p1
+%autopatch -p1
+
 # https://github.com/django-tastypie/django-tastypie/issues/1617
 sed -Ei 
's/(test_apikey_and_authentication_enforce_user|test_is_authenticated)/_\1/' 
tests/core/tests/authentication.py
 
@@ -67,16 +66,16 @@
 %check
 # The tests are doing what is specified in tox.ini
 %{python_expand export PYTHONPATH=${PWD}:${PWD}/tests/
-django-admin.py-%{$python_bin_suffix} test -p '*' core.tests 
--settings=settings_core
-django-admin.py-%{$python_bin_suffix} test basic.tests 
--settings=settings_basic
-django-admin.py-%{$python_bin_suffix} test related_resource.tests 
--settings=settings_related
-django-admin.py-%{$python_bin_suffix} test alphanumeric.tests 
--settings=settings_alphanumeric
-django-admin.py-%{$python_bin_suffix} test authorization.tests 
--settings=settings_authorization
-django-admin.py-%{$python_bin_suffix} test content_gfk.tests 
--settings=settings_content_gfk
-django-admin.py-%{$python_bin_suffix} test customuser.tests 
--settings=settings_customuser
-django-admin.py-%{$python_bin_suffix} test namespaced.tests 
--settings=settings_namespaced
-django-admin.py-%{$python_bin_suffix} test slashless.tests 
--settings=settings_slashless
-django-admin.py-%{$python_bin_suffix} test validation.tests 
--settings=settings_validation
+django-admin-%{$python_bin_suffix} test -v 3 -p '*' core.tests 
--settings=settings_core
+django-admin-%{$python_bin_suffix} test -v 3 basic.tests 
--settings=settings_basic
+django-admin-%{$python_bin_suffix} test -v 3 related_resource.tests 
--settings=settings_related
+django-admin-%{$python_bin_suffix} test -v 3 alphanumeric.tests 
--settings=settings_alphanumeric
+django-admin-%{$python_bin_suffix} test -v 3 authorization.tests 
--settings=settings_authorization
+django-admin-%{$python_bin_suffix} test -v 3 content_gfk.tests 
--settings=settings_content_gfk
+django-admin-%{$python_bin_suffix} test -v 3 customuser.tests 
--settings=settings_customuser
+django-admin-%{$python_bin_suffix} test -v 3 namespaced.tests 
--settings=settings_namespaced
+django-admin-%{$python_bin_suffix} test -v 3 slashless.tests 
--settings=settings_slashless
+django-admin-%{$python_bin_suffix} test -v 3 validation.tests 
--settings=settings_validation
 }
 
 %files %{python_files}

++++++ v0.14.3.tar.gz -> v0.14.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-tastypie-0.14.3/.github/workflows/python-package.yml 
new/django-tastypie-0.14.4/.github/workflows/python-package.yml
--- old/django-tastypie-0.14.3/.github/workflows/python-package.yml     
1970-01-01 01:00:00.000000000 +0100
+++ new/django-tastypie-0.14.4/.github/workflows/python-package.yml     
2022-01-04 02:18:10.000000000 +0100
@@ -0,0 +1,59 @@
+# This workflow will install Python dependencies, run tests and lint with a 
variety of Python versions
+# For more information see: 
https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
+
+name: Test Matrix
+
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
+        django-version: ["2.2", "3.2", "4.0"]  # Todo: add "dev" back
+        exclude:
+           - python-version: "3.6"
+             django-version: "4.0"
+#           - python-version: "3.6"
+#             django-version: "dev"
+           - python-version: "3.7"
+             django-version: "4.0"
+#           - python-version: "3.7"
+#             django-version: "dev"
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Install OS dependencies
+      run: |
+        sudo apt install -y binutils libproj-dev gdal-bin 
libsqlite3-mod-spatialite
+
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v2
+      with:
+        python-version: ${{ matrix.python-version }}
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip wheel virtualenv tox coveralls
+    - name: Erase cached coverage
+      run: |
+        coverage erase
+    - name: Flake8
+      run: |
+        tox -e py${{matrix.python-version}}-flake8
+    - name: Docs
+      run: |
+        tox -e py${{matrix.python-version}}-docs
+    - name: Test with Tox
+      run: |
+        tox -e py${{matrix.python-version}}-dj${{matrix.django-version}}
+    - name: Upload coverage data to coveralls.io
+      run: coveralls --service=github
+      continue-on-error: true
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}      
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/.travis.yml 
new/django-tastypie-0.14.4/.travis.yml
--- old/django-tastypie-0.14.3/.travis.yml      2020-01-06 15:43:54.000000000 
+0100
+++ new/django-tastypie-0.14.4/.travis.yml      1970-01-01 01:00:00.000000000 
+0100
@@ -1,68 +0,0 @@
-sudo: false
-dist: bionic
-
-language: python
-
-python:
-  - "2.7"
-  - "3.5"
-  - "3.6"
-  - "3.7"
-
-env:
-  - MODE=flake8
-  - MODE=flake8-strict
-  - MODE=docs
-  - DJANGO_VERSION=dj111
-  - DJANGO_VERSION=dj22
-  - DJANGO_VERSION=dj30
-  - DJANGO_VERSION=djdev
-
-matrix:
-  allow_failures:
-    - env: DJANGO_VERSION=djdev
-    - env: MODE=flake8-strict
-  exclude:
-    - python: "2.7"
-      env: DJANGO_VERSION=djdev
-    - python: "2.7"
-      env: DJANGO_VERSION=dj22
-    - python: "2.7"
-      env: DJANGO_VERSION=dj30
-    - python: "3.5"
-      env: DJANGO_VERSION=dj30
-    - python: "3.5"
-      env: DJANGO_VERSION=djdev
-
-before_install:
-  - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 762E3157
-  
-addons:
-  apt:
-    packages:
-    - binutils
-    - libproj-dev
-    - gdal-bin
-    - libsqlite3-mod-spatialite
-
-cache:
-  directories:
-    - $HOME/.cache/pip
-
-before_cache:
-  - rm -f $HOME/.cache/pip/log/debug.log
-
-# command to install dependencies
-install:
-  - pip install -U pip
-  - pip install -U wheel virtualenv
-  - pip install tox coveralls
-  
-after_success:
-    - coveralls
-
-# command to run tests
-script:
-    - apt list --installed
-    - coverage erase
-    - tox -e py${TRAVIS_PYTHON_VERSION/./}-${DJANGO_VERSION}${MODE}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/README.rst 
new/django-tastypie-0.14.4/README.rst
--- old/django-tastypie-0.14.3/README.rst       2020-01-06 15:43:54.000000000 
+0100
+++ new/django-tastypie-0.14.4/README.rst       2022-01-04 02:18:10.000000000 
+0100
@@ -6,8 +6,8 @@
     :target: https://django-tastypie.readthedocs.io/
     :alt: Docs
 
-.. image:: 
https://travis-ci.org/django-tastypie/django-tastypie.svg?branch=master
-    :target: https://travis-ci.org/django-tastypie/django-tastypie
+.. image:: 
https://github.com/django-tastypie/django-tastypie/actions/workflows/python-package.yml/badge.svg
+    :target: https://github.com/django-tastypie/django-tastypie/actions
     :alt: CI
 
 .. image:: 
https://coveralls.io/repos/django-tastypie/django-tastypie/badge.svg?service=github
@@ -34,8 +34,8 @@
 Core
 ----
 
-* Python 2.7+ or Python 3.4+ (Whatever is supported by your version of Django)
-* Django 1.11, 2.2 (LTS releases) or Django 3.0 (latest release)
+* Python 3.6+, preferably 3.8+ (Whatever is supported by your version of 
Django)
+* Django 2.2, 3.2 (LTS releases) or Django 4.0 (latest release)
 * dateutil (http://labix.org/python-dateutil) >= 2.1
 
 Format Support
@@ -71,7 +71,7 @@
 
     # urls.py
     # =======
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from tastypie.api import Api
     from myapp.api import EntryResource
 
@@ -80,7 +80,7 @@
 
     urlpatterns = [
         # The normal jazz here then...
-        url(r'^api/', include(v1_api.urls)),
+        re_path(r'^api/', include(v1_api.urls)),
     ]
 
 That gets you a fully working, read-write API for the ``Entry`` model that
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/api.rst 
new/django-tastypie-0.14.4/docs/api.rst
--- old/django-tastypie-0.14.3/docs/api.rst     2020-01-06 15:43:54.000000000 
+0100
+++ new/django-tastypie-0.14.4/docs/api.rst     2022-01-04 02:18:10.000000000 
+0100
@@ -17,7 +17,7 @@
 A sample api definition might look something like (usually located in a
 URLconf)::
 
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from tastypie.api import Api
     from myapp.api.resources import UserResource, EntryResource
 
@@ -27,7 +27,7 @@
 
     # Standard bits...
     urlpatterns = [
-        url(r'^api/', include(v1_api.urls)),
+        re_path(r'^api/', include(v1_api.urls)),
     ]
 
 For namespaced urls see :ref:`namespaces`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/code/myproject/urls.py 
new/django-tastypie-0.14.4/docs/code/myproject/urls.py
--- old/django-tastypie-0.14.3/docs/code/myproject/urls.py      2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/code/myproject/urls.py      2022-01-04 
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 from django.contrib import admin
 
 urlpatterns = [
@@ -6,5 +6,5 @@
     # url(r'^$', 'myproject.views.home', name='home'),
     # url(r'^blog/', include('blog.urls')),
 
-    url(r'^admin/', include(admin.site.urls)),
+    re_path(r'^admin/', include(admin.site.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/cookbook.rst 
new/django-tastypie-0.14.4/docs/cookbook.rst
--- old/django-tastypie-0.14.3/docs/cookbook.rst        2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/cookbook.rst        2022-01-04 
02:18:10.000000000 +0100
@@ -242,7 +242,7 @@
 .. testcode::
 
     # myapp/api/resources.py
-    from django.conf.urls import url
+    from django.urls.conf import re_path
     from django.contrib.auth.models import User
 
 
@@ -253,7 +253,7 @@
 
         def prepend_urls(self):
             return [
-                url(r"^(?P<resource_name>%s)/(?P<username>[\w\d_.-]+)/$" % 
self._meta.resource_name, self.wrap_view('dispatch_detail'), 
name="api_dispatch_detail"),
+                re_path(r"^(?P<resource_name>%s)/(?P<username>[\w\d_.-]+)/$" % 
self._meta.resource_name, self.wrap_view('dispatch_detail'), 
name="api_dispatch_detail"),
             ]
 
 .. testoutput::
@@ -285,13 +285,13 @@
             return super(MyModelResource, self).dispatch(request_type, 
request, **kwargs)
 
     # urls.py
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
 
     mymodel_resource = MyModelResource()
 
     urlpatterns = [
         # The normal jazz here, then...
-        url(r'^api/(?P<username>\w+)/', include(mymodel_resource.urls)),
+        re_path(r'^api/(?P<username>\w+)/', include(mymodel_resource.urls)),
     ]
 
 .. testoutput::
@@ -320,7 +320,7 @@
 
         def prepend_urls(self):
             return [
-                url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/children%s$" % 
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_children'), 
name="api_get_children"),
+                
re_path(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/children%s$" % 
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_children'), 
name="api_get_children"),
             ]
 
         def get_children(self, request, **kwargs):
@@ -350,7 +350,7 @@
 We leave the CRUD methods of the resource alone, choosing to add a new endpoint
 at ``/api/v1/notes/search/``::
 
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from django.core.paginator import Paginator, InvalidPage
     from django.http import Http404
     from haystack.query import SearchQuerySet
@@ -366,7 +366,7 @@
 
         def prepend_urls(self):
             return [
-                url(r"^(?P<resource_name>%s)/search%s$" % 
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), 
name="api_get_search"),
+                re_path(r"^(?P<resource_name>%s)/search%s$" % 
(self._meta.resource_name, trailing_slash()), self.wrap_view('get_search'), 
name="api_get_search"),
             ]
 
         def get_search(self, request, **kwargs):
@@ -560,10 +560,10 @@
             the response format as a file extension, e.g. /api/v1/users.json
             """
             return [
-                url(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" % 
self._meta.resource_name, self.wrap_view('dispatch_list'), 
name="api_dispatch_list"),
-                url(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" % 
self._meta.resource_name, self.wrap_view('get_schema'), name="api_get_schema"),
-                
url(r"^(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)\.(?P<format>\w+)$" % 
self._meta.resource_name, self.wrap_view('get_multiple'), 
name="api_get_multiple"),
-                
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)\.(?P<format>\w+)$" % 
self._meta.resource_name, self.wrap_view('dispatch_detail'), 
name="api_dispatch_detail"),
+                re_path(r"^(?P<resource_name>%s)\.(?P<format>\w+)$" % 
self._meta.resource_name, self.wrap_view('dispatch_list'), 
name="api_dispatch_list"),
+                re_path(r"^(?P<resource_name>%s)/schema\.(?P<format>\w+)$" % 
self._meta.resource_name, self.wrap_view('get_schema'), name="api_get_schema"),
+                
re_path(r"^(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)\.(?P<format>\w+)$" 
% self._meta.resource_name, self.wrap_view('get_multiple'), 
name="api_get_multiple"),
+                
re_path(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)\.(?P<format>\w+)$" % 
self._meta.resource_name, self.wrap_view('dispatch_detail'), 
name="api_dispatch_detail"),
             ]
 
         def determine_format(self, request):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/index.rst 
new/django-tastypie-0.14.4/docs/index.rst
--- old/django-tastypie-0.14.3/docs/index.rst   2020-01-06 15:43:54.000000000 
+0100
+++ new/django-tastypie-0.14.4/docs/index.rst   2022-01-04 02:18:10.000000000 
+0100
@@ -61,7 +61,7 @@
 
 4. In your root URLconf, add the following code (around where the admin code 
might be)::
 
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from tastypie.api import Api
     from my_app.api.resources import MyModelResource
 
@@ -71,7 +71,7 @@
     urlpatterns = [
       # ...more URLconf bits here...
       # Then add:
-      url(r'^api/', include(v1_api.urls)),
+      re_path(r'^api/', include(v1_api.urls)),
     ]
 
 5. Hit http://localhost:8000/api/v1/?format=json in your browser!
@@ -83,8 +83,8 @@
 Core
 ----
 
-* Python 2.7+ or Python 3.4+ (Whatever is supported by your version of Django)
-* Django 1.11, 2.2 (LTS releases) or Django 3.0 (latest release)
+* Python 3.6+, preferably 3.8+ (Whatever is supported by your version of 
Django)
+* Django 2.2, 3.2 (LTS releases) or Django 4.0 (latest release)
 * dateutil (http://labix.org/python-dateutil) >= 2.1
 
 Format Support
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/interacting.rst 
new/django-tastypie-0.14.4/docs/interacting.rst
--- old/django-tastypie-0.14.3/docs/interacting.rst     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/interacting.rst     2022-01-04 
02:18:10.000000000 +0100
@@ -45,7 +45,7 @@
 
 
     # urls.py
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from tastypie.api import Api
     from myapp.api.resources import EntryResource, UserResource
 
@@ -55,8 +55,8 @@
 
     urlpatterns = [
         # The normal jazz here...
-        url(r'^blog/', include('myapp.urls')),
-        url(r'^api/', include(v1_api.urls)),
+        re_path(r'^blog/', include('myapp.urls')),
+        re_path(r'^api/', include(v1_api.urls)),
     ]
 
 Let's fire up a shell & start exploring the API!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/namespaces.rst 
new/django-tastypie-0.14.4/docs/namespaces.rst
--- old/django-tastypie-0.14.3/docs/namespaces.rst      2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/namespaces.rst      2022-01-04 
02:18:10.000000000 +0100
@@ -8,7 +8,7 @@
 
 A sample definition of your API in this case would be something like::
 
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from tastypie.api import NamespacedApi
     from my_application.api.resources import NamespacedUserResource
 
@@ -16,7 +16,7 @@
     api.register(NamespacedUserResource())
 
     urlpatterns = [
-        url(r'^api/', include(api.urls, namespace='special')),
+        re_path(r'^api/', include(api.urls, namespace='special')),
     ]
 
 And your model resource::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/release_notes/index.rst 
new/django-tastypie-0.14.4/docs/release_notes/index.rst
--- old/django-tastypie-0.14.3/docs/release_notes/index.rst     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/release_notes/index.rst     2022-01-04 
02:18:10.000000000 +0100
@@ -5,6 +5,7 @@
    :maxdepth: 1
 
    dev
+   v0.14.4
    v0.14.3
    v0.14.2
    v0.14.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-tastypie-0.14.3/docs/release_notes/v0.14.4.rst 
new/django-tastypie-0.14.4/docs/release_notes/v0.14.4.rst
--- old/django-tastypie-0.14.3/docs/release_notes/v0.14.4.rst   1970-01-01 
01:00:00.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/release_notes/v0.14.4.rst   2022-01-04 
02:18:10.000000000 +0100
@@ -0,0 +1,9 @@
+v0.14.4
+=======
+
+:date: 2022-01-03
+
+Added support for Django 4.0.
+Drops explicit support for Django 3.0, 3.1 (non-LTS).
+Drops all support for Python 2.
+Fixes a TZ bug in date-formatted Retry-After responses from throttling 
revealed by Django 4.0's switch to Zoneinfo.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/docs/tutorial.rst 
new/django-tastypie-0.14.4/docs/tutorial.rst
--- old/django-tastypie-0.14.3/docs/tutorial.rst        2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/docs/tutorial.rst        2022-01-04 
02:18:10.000000000 +0100
@@ -131,15 +131,15 @@
 ``urls``::
 
     # urls.py
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from myapp.api import EntryResource
 
     entry_resource = EntryResource()
 
     urlpatterns = [
         # The normal jazz here...
-        url(r'^blog/', include('myapp.urls')),
-        url(r'^api/', include(entry_resource.urls)),
+        re_path(r'^blog/', include('myapp.urls')),
+        re_path(r'^api/', include(entry_resource.urls)),
     ]
 
 Now it's just a matter of firing up server (``./manage.py runserver``) and
@@ -258,7 +258,7 @@
 following::
 
     # urls.py
-    from django.conf.urls import url, include
+    from django.urls.conf import re_path, include
     from tastypie.api import Api
     from myapp.api import EntryResource, UserResource
 
@@ -268,8 +268,8 @@
 
     urlpatterns = [
         # The normal jazz here...
-        url(r'^blog/', include('myapp.urls')),
-        url(r'^api/', include(v1_api.urls)),
+        re_path(r'^blog/', include('myapp.urls')),
+        re_path(r'^api/', include(v1_api.urls)),
     ]
 
 Note that we're now creating an :class:`~tastypie.api.Api` instance,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/__init__.py 
new/django-tastypie-0.14.4/tastypie/__init__.py
--- old/django-tastypie-0.14.3/tastypie/__init__.py     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/__init__.py     2022-01-04 
02:18:10.000000000 +0100
@@ -3,7 +3,7 @@
 
 __author__ = 'Daniel Lindsley & the Tastypie core team'
 
-VERSION = (0, 14, 3)
+VERSION = (0, 14, 4)
 
 __short_version__ = '.'.join(map(str, VERSION[0:2]))
 __version__ = ''.join(['.'.join(map(str, VERSION[0:3])), ''.join(VERSION[3:])])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/api.py 
new/django-tastypie-0.14.4/tastypie/api.py
--- old/django-tastypie-0.14.3/tastypie/api.py  2020-01-06 15:43:54.000000000 
+0100
+++ new/django-tastypie-0.14.4/tastypie/api.py  2022-01-04 02:18:10.000000000 
+0100
@@ -1,6 +1,5 @@
 from __future__ import unicode_literals
 import warnings
-from django.conf.urls import url, include
 from django.core.exceptions import ImproperlyConfigured
 from django.http import HttpResponse, HttpResponseBadRequest
 from tastypie.compat import reverse
@@ -9,6 +8,7 @@
 from tastypie.utils import is_valid_jsonp_callback_value, string_to_python, 
trailing_slash
 from tastypie.utils.mime import determine_format, build_content_type
 from tastypie.resources import Resource
+from django.urls.conf import re_path, include
 
 
 class Api(object):
@@ -103,12 +103,12 @@
         ``Resources`` beneath it.
         """
         pattern_list = [
-            url(r"^(?P<api_name>%s)%s$" % (self.api_name, trailing_slash), 
self.wrap_view('top_level'), name="api_%s_top_level" % self.api_name),
+            re_path(r"^(?P<api_name>%s)%s$" % (self.api_name, trailing_slash), 
self.wrap_view('top_level'), name="api_%s_top_level" % self.api_name),
         ]
 
         for name in sorted(self._registry.keys()):
             self._registry[name].api_name = self.api_name
-            pattern_list.append(url(r"^(?P<api_name>%s)/" % self.api_name, 
include(self._registry[name].urls)))
+            pattern_list.append(re_path(r"^(?P<api_name>%s)/" % self.api_name, 
include(self._registry[name].urls)))
 
         urlpatterns = self.prepend_urls()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/authentication.py 
new/django-tastypie-0.14.4/tastypie/authentication.py
--- old/django-tastypie-0.14.3/tastypie/authentication.py       2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/authentication.py       2022-01-04 
02:18:10.000000000 +0100
@@ -9,13 +9,13 @@
 from django.conf import settings
 from django.contrib.auth import authenticate
 from django.core.exceptions import ImproperlyConfigured
-from django.middleware.csrf import _sanitize_token, constant_time_compare
-from django.utils.translation import ugettext as _
+from django.middleware.csrf import _sanitize_token
+from django.utils.translation import gettext as _
 
 from six.moves.urllib.parse import urlparse
 
 from tastypie.compat import (
-    get_user_model, get_username_field, unsalt_token, is_authenticated
+    get_user_model, get_username_field, compare_sanitized_tokens, 
InvalidTokenFormat
 )
 from tastypie.http import HttpUnauthorized
 
@@ -306,10 +306,10 @@
         # the serialized bodies.
 
         if request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
-            return is_authenticated(request.user)
+            return request.user.is_authenticated
 
         if getattr(request, '_dont_enforce_csrf_checks', False):
-            return is_authenticated(request.user)
+            return request.user.is_authenticated
 
         csrf_token = 
_sanitize_token(request.COOKIES.get(settings.CSRF_COOKIE_NAME, ''))
 
@@ -325,13 +325,15 @@
                 return False
 
         request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
-        request_csrf_token = _sanitize_token(request_csrf_token)
+        try:
+            request_csrf_token = _sanitize_token(request_csrf_token)
+        except InvalidTokenFormat:
+            return False
 
-        if not constant_time_compare(unsalt_token(request_csrf_token),
-                                     unsalt_token(csrf_token)):
+        if not compare_sanitized_tokens(request_csrf_token, csrf_token):
             return False
 
-        return is_authenticated(request.user)
+        return request.user.is_authenticated
 
     def get_identifier(self, request):
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/compat.py 
new/django-tastypie-0.14.4/tastypie/compat.py
--- old/django-tastypie-0.14.3/tastypie/compat.py       2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/compat.py       2022-01-04 
02:18:10.000000000 +0100
@@ -13,16 +13,6 @@
 AUTH_USER_MODEL = settings.AUTH_USER_MODEL
 
 
-def is_authenticated(user):
-    """
-    Django is changing User.is_authenticated into a property.  Calling it
-    will be deprecated by Django 2.0 and a warning in 1.10+.
-    """
-    if django.VERSION < (1, 10):
-        return bool(user.is_authenticated())
-    return bool(user.is_authenticated)
-
-
 def get_username_field():
     return get_user_model().USERNAME_FIELD
 
@@ -31,21 +21,16 @@
     return meta.model_name
 
 
-atomic_decorator = django.db.transaction.atomic
-
-# Compatability for salted vs unsalted CSRF tokens;
-# Django 1.10's _sanitize_token also hashes it, so it can't be compared 
directly.
-# Solution is to call _sanitize_token on both tokens, then unsalt or noop both
-try:
-    from django.middleware.csrf import _unsalt_cipher_token
-
-    def unsalt_token(token):
-        return _unsalt_cipher_token(token)
-except ImportError:
+def is_ajax(request):
+    """
+    Handle multiple ways of detecting an ajax request.  Probably nearly 
useless.
+    """
+    if hasattr(request, 'is_ajax'):
+        return request.is_ajax()
+    return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
 
-    def unsalt_token(token):
-        return token
 
+atomic_decorator = django.db.transaction.atomic
 
 # force_text deprecated in 2.2, removed in 3.0
 # note that in 1.1.x, force_str and force_text both exist, but force_str 
behaves
@@ -54,3 +39,38 @@
     from django.utils.encoding import force_text as force_str  # noqa
 else:
     from django.utils.encoding import force_str  # noqa
+
+
+compare_sanitized_tokens = None
+
+# django 4.0
+try:
+    from django.middleware.csrf import _does_token_match, InvalidTokenFormat
+    compare_sanitized_tokens = _does_token_match
+except ImportError:
+    pass
+
+
+# django 3.2
+if compare_sanitized_tokens is None:
+    try:
+        from django.middleware.csrf import _compare_masked_tokens
+        compare_sanitized_tokens = _compare_masked_tokens
+        class InvalidTokenFormat(Exception):  # noqa
+            pass
+    except ImportError:
+        pass
+
+# django 2.2
+if compare_sanitized_tokens is None:
+    try:
+        from django.middleware.csrf import _unsalt_cipher_token, 
constant_time_compare
+
+        def compare_sanitized_tokens(request_csrf_token, csrf_token):
+            return 
constant_time_compare(_unsalt_cipher_token(request_csrf_token),
+                                         _unsalt_cipher_token(csrf_token))
+
+        class InvalidTokenFormat(Exception):  # noqa
+            pass
+    except ImportError:  # pragma: no cover
+        raise ImportError("Couldn't find a way to compare csrf tokens safely") 
 # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/resources.py 
new/django-tastypie-0.14.4/tastypie/resources.py
--- old/django-tastypie-0.14.3/tastypie/resources.py    2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/resources.py    2022-01-04 
02:18:10.000000000 +0100
@@ -10,13 +10,14 @@
 from wsgiref.handlers import format_date_time
 
 from django.conf import settings
-from django.conf.urls import url
 from django.core.exceptions import (
     ObjectDoesNotExist, MultipleObjectsReturned, ValidationError, 
FieldDoesNotExist
 )
 from django.core.signals import got_request_exception
 from django.core.exceptions import ImproperlyConfigured
 from django.db.models.fields.related import ForeignKey
+from django.urls.conf import re_path
+from tastypie.utils.timezone import make_naive_utc
 try:
     from django.contrib.gis.db.models.fields import GeometryField
 except (ImproperlyConfigured, ImportError):
@@ -40,7 +41,7 @@
 from tastypie.authorization import ReadOnlyAuthorization
 from tastypie.bundle import Bundle
 from tastypie.cache import NoCache
-from tastypie.compat import NoReverseMatch, reverse, Resolver404, 
get_script_prefix
+from tastypie.compat import NoReverseMatch, reverse, Resolver404, 
get_script_prefix, is_ajax
 from tastypie.constants import ALL, ALL_WITH_RELATIONS
 from tastypie.exceptions import (
     NotFound, BadRequest, InvalidFilterError, HydrationError, InvalidSortError,
@@ -240,7 +241,7 @@
                         # ``Cache-Control`` available then patch the header.
                         patch_cache_control(response, 
**self._meta.cache.cache_control())
 
-                if request.is_ajax() and not 
response.has_header("Cache-Control"):
+                if is_ajax(request) and not 
response.has_header("Cache-Control"):
                     # IE excessively caches XMLHttpRequests, so we're disabling
                     # the browser cache here.
                     # See http://www.enhanceie.com/ie/bugs.asp for details.
@@ -338,10 +339,10 @@
         The standard URLs this ``Resource`` should respond to.
         """
         return [
-            url(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name, 
trailing_slash), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
-            url(r"^(?P<resource_name>%s)/schema%s$" % 
(self._meta.resource_name, trailing_slash), self.wrap_view('get_schema'), 
name="api_get_schema"),
-            url(r"^(?P<resource_name>%s)/set/(?P<%s_list>.*?)%s$" % 
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash), 
self.wrap_view('get_multiple'), name="api_get_multiple"),
-            url(r"^(?P<resource_name>%s)/(?P<%s>.*?)%s$" % 
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash), 
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
+            re_path(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name, 
trailing_slash), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
+            re_path(r"^(?P<resource_name>%s)/schema%s$" % 
(self._meta.resource_name, trailing_slash), self.wrap_view('get_schema'), 
name="api_get_schema"),
+            re_path(r"^(?P<resource_name>%s)/set/(?P<%s_list>.*?)%s$" % 
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash), 
self.wrap_view('get_multiple'), name="api_get_multiple"),
+            re_path(r"^(?P<resource_name>%s)/(?P<%s>.*?)%s$" % 
(self._meta.resource_name, self._meta.detail_uri_name, trailing_slash), 
self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
         ]
 
     def override_urls(self):
@@ -602,7 +603,9 @@
             if isinstance(throttle, int) and not isinstance(throttle, bool):
                 response['Retry-After'] = throttle
             elif isinstance(throttle, datetime):
-                response['Retry-After'] = 
format_date_time(mktime(throttle.timetuple()))
+                # change to UTC (GMT) and make naive, to avoid wsgiref also 
doing an implicit TZ conversion
+                throttle_utc = make_naive_utc(throttle)
+                response['Retry-After'] = 
format_date_time(mktime(throttle_utc.timetuple()))
 
             raise ImmediateHttpResponse(response=response)
 
@@ -1910,7 +1913,7 @@
             result = fields.FloatField
         elif internal_type in ('DecimalField',):
             result = fields.DecimalField
-        elif internal_type in ('IntegerField', 'PositiveIntegerField', 
'PositiveSmallIntegerField', 'SmallIntegerField', 'AutoField', 
'BigIntegerField'):
+        elif internal_type in ('IntegerField', 'PositiveIntegerField', 
'PositiveSmallIntegerField', 'SmallIntegerField', 'AutoField', 
'BigIntegerField', 'BigAutoField'):
             result = fields.IntegerField
         elif internal_type in ('FileField', 'ImageField'):
             result = fields.FileField
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tastypie/utils/timezone.py 
new/django-tastypie-0.14.4/tastypie/utils/timezone.py
--- old/django-tastypie-0.14.3/tastypie/utils/timezone.py       2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tastypie/utils/timezone.py       2022-01-04 
02:18:10.000000000 +0100
@@ -19,6 +19,15 @@
     return value
 
 
+def make_naive_utc(value):
+    """
+    Translate a datetime to UTC, then strip TZ info; useful as a last step 
before creating the
+    Retry-After header.
+    """
+    utc_value = timezone.localtime(value, timezone.utc)
+    return timezone.make_naive(utc_value)
+
+
 def now():
     d = timezone.now()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/alphanumeric/urls.py 
new/django-tastypie-0.14.4/tests/alphanumeric/urls.py
--- old/django-tastypie-0.14.3/tests/alphanumeric/urls.py       2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/alphanumeric/urls.py       2022-01-04 
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 
 
 urlpatterns = [
-    url(r'^api/', include('alphanumeric.api.urls')),
+    re_path(r'^api/', include('alphanumeric.api.urls')),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/authorization/urls.py 
new/django-tastypie-0.14.4/tests/authorization/urls.py
--- old/django-tastypie-0.14.3/tests/authorization/urls.py      2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/authorization/urls.py      2022-01-04 
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import url, include
+from django.urls.conf import include, re_path
 
 from tastypie.api import Api
 
@@ -12,5 +12,5 @@
 v1_api.register(UserResource())
 
 urlpatterns = [
-    url(r'^api/', include(v1_api.urls)),
+    re_path(r'^api/', include(v1_api.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/basic/urls.py 
new/django-tastypie-0.14.4/tests/basic/urls.py
--- old/django-tastypie-0.14.3/tests/basic/urls.py      2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/basic/urls.py      2022-01-04 
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 
 
 urlpatterns = [
-    url(r'^api/', include('basic.api.urls')),
+    re_path(r'^api/', include('basic.api.urls')),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/content_gfk/urls.py 
new/django-tastypie-0.14.4/tests/content_gfk/urls.py
--- old/django-tastypie-0.14.3/tests/content_gfk/urls.py        2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/content_gfk/urls.py        2022-01-04 
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 
 
 urlpatterns = [
-    url(r'^api/', include('content_gfk.api.urls')),
+    re_path(r'^api/', include('content_gfk.api.urls')),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-tastypie-0.14.3/tests/core/migrations/0001_initial.py 
new/django-tastypie-0.14.4/tests/core/migrations/0001_initial.py
--- old/django-tastypie-0.14.3/tests/core/migrations/0001_initial.py    
2020-01-06 15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/migrations/0001_initial.py    
2022-01-04 02:18:10.000000000 +0100
@@ -114,4 +114,10 @@
             ],
             bases=('core.note',),
         ),
+        migrations.CreateModel(
+            name='BigAutoNowModel',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False, 
verbose_name='ID')),
+            ],
+        ),
     ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/models.py 
new/django-tastypie-0.14.4/tests/core/models.py
--- old/django-tastypie-0.14.3/tests/core/models.py     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/models.py     2022-01-04 
02:18:10.000000000 +0100
@@ -97,6 +97,13 @@
         app_label = 'core'
 
 
+class BigAutoNowModel(models.Model):
+    id = models.BigAutoField(primary_key=True)
+
+    class Meta:
+        app_label = 'core'
+
+
 class Counter(models.Model):
     name = models.CharField(max_length=30)
     slug = models.SlugField(unique=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/tests/__init__.py 
new/django-tastypie-0.14.4/tests/core/tests/__init__.py
--- old/django-tastypie-0.14.3/tests/core/tests/__init__.py     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/__init__.py     2022-01-04 
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
+import doctest
 import warnings
 warnings.simplefilter('ignore', Warning)  # noqa
-import doctest
 
 from core.tests.api import *  # noqa
 from core.tests.authentication import *  # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/tests/api_urls.py 
new/django-tastypie-0.14.4/tests/core/tests/api_urls.py
--- old/django-tastypie-0.14.3/tests/core/tests/api_urls.py     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/api_urls.py     2022-01-04 
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 
 from core.tests.api import Api, NoteResource, UserResource
 
@@ -8,5 +8,5 @@
 api.register(UserResource())
 
 urlpatterns = [
-    url(r'^api/', include(api.urls)),
+    re_path(r'^api/', include(api.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-tastypie-0.14.3/tests/core/tests/manual_urls.py 
new/django-tastypie-0.14.4/tests/core/tests/manual_urls.py
--- old/django-tastypie-0.14.3/tests/core/tests/manual_urls.py  2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/manual_urls.py  2022-01-04 
02:18:10.000000000 +0100
@@ -1,9 +1,9 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 from core.tests.resources import NoteResource
 
 
 note_resource = NoteResource()
 
 urlpatterns = [
-    url(r'^', include(note_resource.urls)),
+    re_path(r'^', include(note_resource.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-tastypie-0.14.3/tests/core/tests/resource_urls.py 
new/django-tastypie-0.14.4/tests/core/tests/resource_urls.py
--- old/django-tastypie-0.14.3/tests/core/tests/resource_urls.py        
2020-01-06 15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/resource_urls.py        
2022-01-04 02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 from django.contrib.auth.models import User
 from tastypie import fields
 from tastypie.resources import ModelResource
@@ -33,5 +33,5 @@
 api.register(SubjectResource())
 
 urlpatterns = [
-    url(r'^api/', include(api.urls)),
+    re_path(r'^api/', include(api.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/core/tests/resources.py 
new/django-tastypie-0.14.4/tests/core/tests/resources.py
--- old/django-tastypie-0.14.3/tests/core/tests/resources.py    2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/core/tests/resources.py    2022-01-04 
02:18:10.000000000 +0100
@@ -18,6 +18,7 @@
 from django.core.cache import cache
 from django.core.exceptions import FieldError, MultipleObjectsReturned, 
ObjectDoesNotExist, ImproperlyConfigured
 from django.core import mail
+from time import mktime
 try:
     from django.urls import reverse
 except ImportError:
@@ -36,7 +37,7 @@
     UnsupportedSerializationFormat, UnsupportedDeserializationFormat,
 )
 from tastypie import fields, http
-from tastypie.compat import is_authenticated, force_str
+from tastypie.compat import force_str
 from tastypie.paginator import Paginator
 from tastypie.resources import (
     ALL, ALL_WITH_RELATIONS, convert_post_to_put, convert_post_to_patch,
@@ -49,7 +50,7 @@
 
 from core.models import (
     Note, NoteWithEditor, Subject, MediaBit, AutoNowNote, DateRecord, Counter,
-    MyDefaultPKModel, MyUUIDModel, MyRelatedUUIDModel,
+    MyDefaultPKModel, MyUUIDModel, MyRelatedUUIDModel, BigAutoNowModel,
 )
 from core.tests.mocks import MockRequest
 from core.utils import adjust_schema, SimpleHandler
@@ -1056,6 +1057,19 @@
         return '/api/v1/autonownotes/%s/' % bundle_or_obj.obj.id
 
 
+class BigAutoNowModelResource(ModelResource):
+    class Meta:
+        resource_name = 'bigautonowmodels'
+        queryset = BigAutoNowModel.objects.all()
+        authorization = Authorization()
+
+    def get_resource_uri(self, bundle_or_obj=None, 
url_name='api_dispatch_list'):
+        if bundle_or_obj is None:
+            return '/api/v1/bigautonowmodels/'
+
+        return '/api/v1/bigautonowmodels/%s/' % bundle_or_obj.obj.id
+
+
 class CustomPaginator(Paginator):
     def page(self):
         data = super(CustomPaginator, self).page()
@@ -1338,7 +1352,7 @@
 class PerUserAuthorization(Authorization):
     def read_list(self, object_list, bundle):
         if bundle.request and hasattr(bundle.request, 'user'):
-            if is_authenticated(bundle.request.user):
+            if bundle.request.user.is_authenticated:
                 object_list = object_list.filter(author=bundle.request.user)
             else:
                 object_list = object_list.none()
@@ -1661,6 +1675,20 @@
         self.assertEqual(annr.fields['updated'].readonly, False)
         self.assertEqual(annr.fields['updated'].unique, False)
 
+    def test_big_auto_field(self):
+        annr = BigAutoNowModelResource()
+        self.assertEqual(len(annr.fields), 2)
+        self.assertEqual(sorted(annr.fields.keys()), ['id', 'resource_uri'])
+
+        self.assertTrue(isinstance(annr.fields['id'], fields.IntegerField))
+        self.assertEqual(annr.fields['id'].attribute, 'id')
+        self.assertEqual(annr.fields['id'].blank, True)
+        self.assertEqual(annr.fields['id']._default, '')
+        self.assertEqual(annr.fields['id'].instance_name, 'id')
+        self.assertEqual(annr.fields['id'].null, False)
+        self.assertEqual(annr.fields['id'].readonly, False)
+        self.assertEqual(annr.fields['id'].unique, True)
+
     def test_invalid_model_resource(self):
         """
         Test error message regarding ModelResource lacking object_class and 
queryset.
@@ -4156,10 +4184,71 @@
     @patch('tastypie.throttle.time')
     @override_settings(DEBUG=False)
     def test_check_datetime_throttling(self, mocked_time):
-        mocked_time.time.return_value = time.time()
 
         retry_after = datetime.datetime(year=2014, month=8, day=8, hour=8, 
minute=55, tzinfo=timezone.utc)
-        retry_after_str = 'Fri, 08 Aug 2014 14:55:00 GMT'
+        mocked_time.time.return_value = mktime(retry_after.timetuple())
+        retry_after_str = 'Fri, 08 Aug 2014 08:55:00 GMT'
+
+        resource = ThrottledNoteResource()
+        _orginal_throttle = resource._meta.throttle
+
+        class DatetimeThrottle(resource._meta.throttle.__class__):
+            def should_be_throttled(self, *args, **kwargs):
+                ret = super(DatetimeThrottle, self).should_be_throttled(*args, 
**kwargs)
+                if ret:
+                    return retry_after
+                return False
+        resource._meta.throttle = DatetimeThrottle(
+            throttle_at=resource._meta.throttle.throttle_at,
+            timeframe=resource._meta.throttle.timeframe,
+            expiration=resource._meta.throttle.expiration
+        )
+
+        request = HttpRequest()
+        request.GET = {'format': 'json'}
+        request.method = 'GET'
+
+        # Not throttled.
+        resp = resource.dispatch('list', request)
+        self.assertEqual(resp.status_code, 200)
+        self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 1)
+
+        # Not throttled.
+        resp = resource.dispatch('list', request)
+        self.assertEqual(resp.status_code, 200)
+        self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+        # Throttled.
+        with self.assertRaises(ImmediateHttpResponse) as ctx:
+            resp = resource.dispatch('list', request)
+        e = ctx.exception
+        self.assertEqual(e.response.status_code, 429)
+        self.assertEqual(e.response['Retry-After'], retry_after_str)
+        self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+        # Throttled.
+        with self.assertRaises(ImmediateHttpResponse) as ctx:
+            resp = resource.dispatch('list', request)
+        e = ctx.exception
+        self.assertEqual(e.response.status_code, 429)
+        self.assertEqual(e.response['Retry-After'], retry_after_str)
+        self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+        # Check the ``wrap_view``.
+        resp = resource.wrap_view('dispatch_list')(request)
+        self.assertEqual(resp.status_code, 429)
+        self.assertEqual(resp['Retry-After'], retry_after_str)
+        self.assertEqual(len(cache.get('noaddr_nohost_accesses')), 2)
+
+        resource._meta.throttle = _orginal_throttle
+
+    @patch('tastypie.throttle.time')
+    @override_settings(DEBUG=False, USE_TZ=False)
+    def test_check_datetime_throttling_notz(self, mocked_time):
+
+        retry_after = datetime.datetime(year=2014, month=8, day=8, hour=8, 
minute=55, tzinfo=timezone.utc)
+        mocked_time.time.return_value = mktime(retry_after.timetuple())
+        retry_after_str = 'Fri, 08 Aug 2014 08:55:00 GMT'
 
         resource = ThrottledNoteResource()
         _orginal_throttle = resource._meta.throttle
@@ -4937,7 +5026,7 @@
         self.assertEqual(resp.status_code, 200)
         self.assertEqual(resp.content.decode('utf-8'), '{"content": "This is 
my very first post using my shiny new API. Pretty sweet, huh?", "created": 
"2010-03-30T20:05:00", "id": 1, "is_active": true, "resource_uri": 
"/api/v1/notes/1/", "slug": "first-post", "title": "First Post!", "updated": 
"2010-03-30T20:05:00"}')
         self.assertTrue(resp.has_header('Cache-Control'))
-        self.assertEqual(resp._headers['cache-control'], ('Cache-Control', 
'no-cache'))
+        self.assertEqual(resp['Cache-Control'], 'no-cache')
 
         # Now as Ajax.
         request.META = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
@@ -4945,7 +5034,7 @@
         self.assertEqual(resp.status_code, 200)
         self.assertEqual(resp.content.decode('utf-8'), '{"content": "This is 
my very first post using my shiny new API. Pretty sweet, huh?", "created": 
"2010-03-30T20:05:00", "id": 1, "is_active": true, "resource_uri": 
"/api/v1/notes/1/", "slug": "first-post", "title": "First Post!", "updated": 
"2010-03-30T20:05:00"}')
         self.assertTrue(resp.has_header('cache-control'))
-        self.assertEqual(resp._headers['cache-control'], ('Cache-Control', 
'no-cache'))
+        self.assertEqual(resp['Cache-Control'], 'no-cache')
 
     def test_custom_paginator(self):
         mock_request = MockRequest()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/gis/urls.py 
new/django-tastypie-0.14.4/tests/gis/urls.py
--- old/django-tastypie-0.14.3/tests/gis/urls.py        2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/gis/urls.py        2022-01-04 
02:18:10.000000000 +0100
@@ -1,6 +1,6 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 
 
 urlpatterns = [
-    url(r'^api/', include('gis.api.urls')),
+    re_path(r'^api/', include('gis.api.urls')),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/namespaced/api/urls.py 
new/django-tastypie-0.14.4/tests/namespaced/api/urls.py
--- old/django-tastypie-0.14.3/tests/namespaced/api/urls.py     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/namespaced/api/urls.py     2022-01-04 
02:18:10.000000000 +0100
@@ -1,5 +1,5 @@
 from django.conf import settings
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 from tastypie.api import NamespacedApi
 from namespaced.api.resources import NamespacedNoteResource, 
NamespacedUserResource
 
@@ -14,5 +14,5 @@
     included = include(api.urls, namespace='special')
 
 urlpatterns = [
-    url(r'^api/', included),
+    re_path(r'^api/', included),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/profilingtests/urls.py 
new/django-tastypie-0.14.4/tests/profilingtests/urls.py
--- old/django-tastypie-0.14.3/tests/profilingtests/urls.py     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/profilingtests/urls.py     2022-01-04 
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 
 from tastypie.api import Api
 
@@ -10,5 +10,5 @@
 api.register(UserResource())
 
 urlpatterns = [
-    url(r'^api/', include(api.urls)),
+    re_path(r'^api/', include(api.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/requirements.txt 
new/django-tastypie-0.14.4/tests/requirements.txt
--- old/django-tastypie-0.14.3/tests/requirements.txt   2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/requirements.txt   2022-01-04 
02:18:10.000000000 +0100
@@ -4,5 +4,5 @@
 defusedxml
 lxml
 mock<1.1.0
-pytz==2013b0
+pytz==2021.1
 PyYAML
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/settings.py 
new/django-tastypie-0.14.4/tests/settings.py
--- old/django-tastypie-0.14.3/tests/settings.py        2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/settings.py        2022-01-04 
02:18:10.000000000 +0100
@@ -38,6 +38,7 @@
         'NAME': DATABASE_NAME,
     }
 }
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
 
 ALLOWED_HOSTS = ['example.com']
 
@@ -91,3 +92,5 @@
 
 if DJANGO_VERSION >= DJANGO_20:
     
MIDDLEWARE.remove('django.contrib.auth.middleware.SessionAuthenticationMiddleware')
+
+SECURE_REFERRER_POLICY = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/slashless/api/urls.py 
new/django-tastypie-0.14.4/tests/slashless/api/urls.py
--- old/django-tastypie-0.14.3/tests/slashless/api/urls.py      2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/slashless/api/urls.py      2022-01-04 
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 from tastypie.api import Api
 from slashless.api.resources import NoteResource, UserResource
 
@@ -8,5 +8,5 @@
 api.register(UserResource(), canonical=True)
 
 urlpatterns = [
-    url(r'^api/', include(api.urls)),
+    re_path(r'^api/', include(api.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tests/validation/api/urls.py 
new/django-tastypie-0.14.4/tests/validation/api/urls.py
--- old/django-tastypie-0.14.3/tests/validation/api/urls.py     2020-01-06 
15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tests/validation/api/urls.py     2022-01-04 
02:18:10.000000000 +0100
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.urls.conf import include, re_path
 
 from tastypie.api import Api
 
@@ -12,5 +12,5 @@
 api.register(AnnotatedNoteResource(), canonical=True)
 
 urlpatterns = [
-    url(r'^api/', include(api.urls)),
+    re_path(r'^api/', include(api.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-tastypie-0.14.3/tox.ini 
new/django-tastypie-0.14.4/tox.ini
--- old/django-tastypie-0.14.3/tox.ini  2020-01-06 15:43:54.000000000 +0100
+++ new/django-tastypie-0.14.4/tox.ini  2022-01-04 02:18:10.000000000 +0100
@@ -1,32 +1,33 @@
 [tox]
 envlist =
-    py{27}-dj{111}
-    py{36,37}-dj{22,30,dev}
-    py{27,37}-docs,
-    py{27,37}-flake8,
-    py{27,37}-flake8-strict
+    py{3.6,3.7,3.8,3.9,3.10}-dj{2.2,3.2}
+    py{3.8,3.9,3.10}-dj{4.0,dev}
+    py{3.6,3.7,3.8,3.9,3.10}-docs,
+    py{3.6,3.7,3.8,3.9,3.10}-flake8,
+    py{3.8,3.9,3.10}-flake8-strict
 
 skipsdist=True
 
 [testenv]
 usedevelop=True
-test-executable =
-    {envbindir}/coverage run --append --source=tastypie,tests 
{envbindir}/django-admin.py
 setenv =
     PYTHONPATH = {toxinidir}:{toxinidir}/tests
     PYTHONWARNINGS = always
+       TESTEXE = {envbindir}/coverage run --append --source=tastypie,tests 
{envbindir}/django-admin.py
+       dj{4.0,dev}: TESTEXE = {envbindir}/coverage run --append 
--source=tastypie,tests {envbindir}/django-admin
+
 commands =
-    dj{111,22,30,dev}: {[testenv]test-executable} test -p '*' core.tests 
--settings=settings_core
-    dj{111,22,30,dev}: {[testenv]test-executable} test basic.tests 
--settings=settings_basic
-    dj{111,22,30,dev}: {[testenv]test-executable} test related_resource.tests 
--settings=settings_related
-    dj{111,22,30,dev}: {[testenv]test-executable} test alphanumeric.tests 
--settings=settings_alphanumeric
-    dj{111,22,30,dev}: {[testenv]test-executable} test authorization.tests 
--settings=settings_authorization
-    dj{111,22,30,dev}: {[testenv]test-executable} test content_gfk.tests 
--settings=settings_content_gfk
-    dj{111,22,30,dev}: {[testenv]test-executable} test customuser.tests 
--settings=settings_customuser
-    dj{111,22,30,dev}: {[testenv]test-executable} test namespaced.tests 
--settings=settings_namespaced
-    dj{111,22,30,dev}: {[testenv]test-executable} test slashless.tests 
--settings=settings_slashless
-    dj{111,22,30,dev}: {[testenv]test-executable} test validation.tests 
--settings=settings_validation
-    dj{111,22,30,dev}: {[testenv]test-executable} test gis.tests 
--settings=settings_gis_spatialite
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test -p '*' core.tests 
--settings=settings_core
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test basic.tests 
--settings=settings_basic
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test related_resource.tests 
--settings=settings_related
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test alphanumeric.tests 
--settings=settings_alphanumeric
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test authorization.tests 
--settings=settings_authorization
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test content_gfk.tests 
--settings=settings_content_gfk
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test customuser.tests 
--settings=settings_customuser
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test namespaced.tests 
--settings=settings_namespaced
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test slashless.tests 
--settings=settings_slashless
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test validation.tests 
--settings=settings_validation
+    dj{2.2,3.2,4.0,dev}: {env:TESTEXE} test gis.tests 
--settings=settings_gis_spatialite
 
     docs: sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html
     docs: sphinx-build -W -b doctest -d {envtmpdir}/doctrees . {envtmpdir}/html
@@ -35,27 +36,23 @@
 
     flake8-strict: {envbindir}/flake8 --ignore=E128 --max-complexity 10 .
 basepython =
-    py27: python2.7
-    py35: python3.5
-    py36: python3.6
-    py37: python3.7
+    py3.6: python3.6
+    py3.7: python3.7
+    py3.8: python3.8
+    py3.9: python3.9
+    py3.10: python3.10
 deps =
-    dj111: Django>=1.11,<1.12
-    dj22: Django>=2.2,<2.3
-    dj30: Django>=3.0,<3.1
-    djdev: https://github.com/django/django/archive/master.tar.gz
-
-    py27-dj{111}: django-oauth-plus==2.2.9
-    py27-dj{111}: python-digest
-    py27-dj{111}: oauth2
-    py27-dj{111}: pysqlite
-    py{35,36,37}-dj{111,22,30,dev}: python3-digest>=1.8b4
-    dj{111,22,30,dev}: -r{toxinidir}/tests/requirements.txt
+    dj2.2: Django>=2.2,<2.3
+    dj3.2: Django>=3.2,<3.3
+    dj4.0: Django>=4.0,<4.1
+    djdev: https://github.com/django/django/archive/refs/heads/main.zip
+
+    dj{2.2,3.2,4.0,dev}: python3-digest>=1.8b4
+    dj{2.2,3.2,4.0,dev}: -r{toxinidir}/tests/requirements.txt
 
+    py{3.6,3.7}-docs: Django~=2.2
+    py{3.7,3.8,3.9,3.10}-docs: Django<4.1
     docs: Sphinx
-    py27-docs: Django<2.0
-    py35-docs: Django<3.0
-    py{36,37}-docs: Django<3.1
     docs: mock
     docs: sphinx_rtd_theme
 

Reply via email to