Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-swapper for openSUSE:Factory 
checked in at 2024-01-29 22:28:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-swapper (Old)
 and      /work/SRC/openSUSE:Factory/.python-swapper.new.1815 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-swapper"

Mon Jan 29 22:28:29 2024 rev:5 rq:1142083 version:1.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-swapper/python-swapper.changes    
2021-05-07 16:46:15.668190956 +0200
+++ /work/SRC/openSUSE:Factory/.python-swapper.new.1815/python-swapper.changes  
2024-01-29 22:29:09.593758077 +0100
@@ -1,0 +2,39 @@
+Sun Jan 21 10:33:17 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 1.3.0:
+  * [change] Allow possibility to point swappable dependency to
+    specific migration number (instead of only to __latest__)
+  * [feature] Add possibility to point swappable dependency to
+    __latest__
+  * [change] Added support for Python 3.9
+  * [change] Added support for Django 3.2 and Django 4.0a1
+  * [change] Dropped support for old Django versions (<2.2)
+  * [change] Dropped support for old Python versions (<3.7)
+  * [feature] Added optional require_ready argument to load_model
+    function
+  * [deps] Verified support for python 3.8
+  * [deps] Added support for Django 3.0 and Django Rest Framework
+    3.11
+  * [deps] Drop python<3.3 support
+  * [deps] Added support for python 3.7
+  * [deps] Django 2 support added
+  * [test] Added tests for swapper.split
+  * #13 [fix] Handle contrib apps and apps with dot in app_label.
+  * [docs] Improved usuability docs
+  * 86e238: [deps] Compatibility with django 1.10 added
+  * #9 [deps] Added support for django 1.9
+  * [deps] Added support for django~=1.6.0
+  * [deps] Added support for Python 3.3
+  * [docs] Fix model reference in README
+  * [docs] Notes for load_model initialization (for more info see
+    #2)
+  * [docs] Added examples for migration scripts
+  * [docs] Documented use of Functions
+  * [fix] Fixed Lookup Error in load_model
+  * [deps] Added support for Django 1.7
+  * [feature] Added swapper.dependency function.
+  * [tests] Added tests
+  * [docs] Added References
+  * Added base functions for swapping models
+
+-------------------------------------------------------------------

Old:
----
  swapper-1.1.2.post1.tar.gz

New:
----
  swapper-1.3.0.tar.gz

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

Other differences:
------------------
++++++ python-swapper.spec ++++++
--- /var/tmp/diff_new_pack.09oihi/_old  2024-01-29 22:29:10.125777361 +0100
+++ /var/tmp/diff_new_pack.09oihi/_new  2024-01-29 22:29:10.125777361 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-swapper
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,21 +16,23 @@
 #
 
 
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%{?sle15_python_module_pythons}
 Name:           python-swapper
-Version:        1.1.2.post1
+Version:        1.3.0
 Release:        0
 Summary:        The unofficial Django swappable models API
 License:        MIT
 Group:          Development/Languages/Python
 URL:            https://github.com/wq/django-swappable-models
 Source:         
https://files.pythonhosted.org/packages/source/s/swapper/swapper-%{version}.tar.gz
-BuildRequires:  %{python_module Django >= 1.6}
+BuildRequires:  %{python_module Django >= 2.0}
+BuildRequires:  %{python_module pip}
 BuildRequires:  %{python_module setuptools_scm}
 BuildRequires:  %{python_module setuptools}
+BuildRequires:  %{python_module wheel}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       python-Django >= 1.6
+Requires:       python-Django >= 2.0
 BuildArch:      noarch
 %python_subpackages
 
@@ -43,10 +45,10 @@
 %setup -q -n swapper-%{version}
 
 %build
-%python_build
+%pyproject_wheel
 
 %install
-%python_install
+%pyproject_install
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
@@ -56,5 +58,6 @@
 %files %{python_files}
 %doc README.md
 %license LICENSE
-%{python_sitelib}/*
+%{python_sitelib}/swapper
+%{python_sitelib}/swapper-%{version}.dist-info
 

++++++ swapper-1.1.2.post1.tar.gz -> swapper-1.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/.github/workflows/ci.yml 
new/swapper-1.3.0/.github/workflows/ci.yml
--- old/swapper-1.1.2.post1/.github/workflows/ci.yml    1970-01-01 
01:00:00.000000000 +0100
+++ new/swapper-1.3.0/.github/workflows/ci.yml  2021-11-12 20:00:49.000000000 
+0100
@@ -0,0 +1,40 @@
+name: Django Swappable Models Build
+
+on:
+  push:
+    branches:
+      - master
+  pull_request:
+    branches:
+      - master
+
+jobs:
+  build:
+    name: Python==${{ matrix.python-version }}
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: [3.7, 3.8, 3.9]
+
+    steps:
+    - uses: actions/checkout@v2
+      with:
+        ref: ${{ github.event.pull_request.head.sha }}
+
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v2
+      with:
+        python-version: ${{ matrix.python-version }}
+
+    - name: Install dependencies
+      run: |
+        pip install -U "pip==20.2.4" wheel setuptools
+        pip install tox tox-gh-actions
+        pip install 
openwisp-utils[qa]@https://github.com/openwisp/openwisp-utils/tarball/master
+
+    - name: QA checks
+      run: ./run-qa-checks
+
+    - name: Test
+      run: tox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/.travis.yml 
new/swapper-1.3.0/.travis.yml
--- old/swapper-1.1.2.post1/.travis.yml 2020-01-15 02:07:09.000000000 +0100
+++ new/swapper-1.3.0/.travis.yml       1970-01-01 01:00:00.000000000 +0100
@@ -1,13 +0,0 @@
-language: python
-dist: xenial
-python:
- - "2.7"
- - "3.4"
- - "3.5"
- - "3.6"
- - "3.7"
- - "3.8"
-install:
- - pip install tox-travis
- - pip install flake8
-script: tox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/CHANGES.rst 
new/swapper-1.3.0/CHANGES.rst
--- old/swapper-1.1.2.post1/CHANGES.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/swapper-1.3.0/CHANGES.rst       2021-11-29 19:44:31.000000000 +0100
@@ -0,0 +1,81 @@
+Changelog
+=========
+
+Verson 1.3.0 [2021-11-29]
+-------------------------
+
+- [change] Allow possibility to point swappable dependency to specific 
migration number
+  (instead of only to ``__latest__``)
+
+Version 1.2.0 [2021-11-12]
+--------------------------
+
+- [feature] Add possibility to point swappable dependency to ``__latest__``
+- [change] Added support for Python 3.9
+- [change] Added support for Django 3.2 and Django 4.0a1
+- [change] Dropped support for old Django versions (<2.2)
+- [change] Dropped support for old Python versions (<3.7)
+- [feature] Added optional ``require_ready`` argument to ``load_model`` 
function
+
+Version 1.1.2 [2020-01-15]
+--------------------------
+
+- [deps] Verified support for python 3.8
+- [deps] Added support for Django 3.0 and Django Rest Framework 3.11
+
+Version 1.1.1 [2019-07-23]
+--------------------------
+
+- [deps] Drop python<3.3 support
+- [deps] Added support for python 3.7
+- [deps] Django 2 support added
+
+Version 1.1.0 [2017-05-11]
+--------------------------
+
+- [test] Added tests for swapper.split
+- `#13 <https://github.com/openwisp/django-swappable-models/pull/13>`_ [fix] 
Handle contrib apps and apps with dot in app_label.
+
+Version 1.0.0 [2016-08-26]
+--------------------------
+
+- [docs] Improved usuability docs
+- `86e238 
<https://github.com/openwisp/django-swappable-models/commit/86e238>`_:
+  [deps] Compatibility with django 1.10 added
+
+Version 0.3.0 [2015-11-17]
+--------------------------
+
+- `#9 <https://github.com/openwisp/django-swappable-models/pull/9>`_ [deps] 
Added support for django 1.9
+
+Version 0.2.2 [2015-06-16]
+--------------------------
+
+- [deps] Added support for django~=1.6.0
+- [deps] Added support for Python 3.3
+- [docs] Fix model reference in README
+- [docs] Notes for load_model initialization (`for more info see #2 
<https://github.com/openwisp/django-swappable-models/issues/2>`_)
+
+Version 0.2.1 [2014-11-18]
+--------------------------
+
+- [docs] Added examples for migration scripts
+- [docs] Documented use of Functions
+- [fix] Fixed Lookup Error in load_model
+
+Version 0.2.0 [2014-09-13]
+--------------------------
+
+- [deps] Added support for Django 1.7
+- [feature] Added `swapper.dependency` function.
+- [tests] Added tests
+
+Version 0.1.1 [2014-01-09]
+--------------------------
+
+- [docs] Added References
+
+Version 0.1.0 [2014-01-09]
+--------------------------
+
+- Added base functions for swapping models
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/LICENSE new/swapper-1.3.0/LICENSE
--- old/swapper-1.1.2.post1/LICENSE     2019-07-23 04:57:18.000000000 +0200
+++ new/swapper-1.3.0/LICENSE   2021-11-12 20:00:49.000000000 +0100
@@ -1,3 +1,4 @@
+Copyright (c) 2021, OpenWISP
 Copyright (c) 2014-2017, S. Andrew Sheppard, http://wq.io/
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/PKG-INFO 
new/swapper-1.3.0/PKG-INFO
--- old/swapper-1.1.2.post1/PKG-INFO    2020-01-15 02:12:58.000000000 +0100
+++ new/swapper-1.3.0/PKG-INFO  2021-11-29 19:51:43.683343000 +0100
@@ -1,14 +1,16 @@
 Metadata-Version: 2.1
 Name: swapper
-Version: 1.1.2.post1
+Version: 1.3.0
 Summary: The unofficial Django swappable models API.
-Home-page: https://github.com/wq/django-swappable-models
+Home-page: https://github.com/openwisp/django-swappable-models
 Author: S. Andrew Sheppard
 Author-email: [email protected]
 License: MIT
 Description: Swapper
         =======
         
+        [![Dependency 
monitoring](https://img.shields.io/librariesio/release/github/openwisp/django-swappable-models)](https://libraries.io/github/openwisp/django-swappable-models)
+        
         #### Django Swappable Models - No longer only for auth.User!
         
         Swapper is an unofficial API for the [undocumented] but very powerful 
Django 
@@ -16,14 +18,14 @@
         arbitrary swappable models in your own reusable apps.
         
         [![Latest PyPI 
Release](https://img.shields.io/pypi/v/swapper.svg)](https://pypi.org/project/swapper)
-        [![Release 
Notes](https://img.shields.io/github/release/wq/django-swappable-models.svg
+        [![Release 
Notes](https://img.shields.io/github/release/openwisp/django-swappable-models.svg
         )](https://github.com/wq/django-swappable-models/releases)
-        
[![License](https://img.shields.io/pypi/l/swapper.svg)](https://github.com/wq/django-swappable-models/blob/master/LICENSE)
-        [![GitHub 
Stars](https://img.shields.io/github/stars/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/stargazers)
-        [![GitHub 
Forks](https://img.shields.io/github/forks/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/network)
-        [![GitHub 
Issues](https://img.shields.io/github/issues/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/issues)
+        
[![License](https://img.shields.io/pypi/l/swapper.svg)](https://github.com/openwisp/django-swappable-models/blob/master/LICENSE)
+        [![GitHub 
Stars](https://img.shields.io/github/stars/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/stargazers)
+        [![GitHub 
Forks](https://img.shields.io/github/forks/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/network)
+        [![GitHub 
Issues](https://img.shields.io/github/issues/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/issues)
         
-        [![Travis Build 
Status](https://img.shields.io/travis/wq/django-swappable-models.svg)](https://travis-ci.org/wq/django-swappable-models)
+        [![Build 
Status](https://github.com/openwisp/django-swappable-models/actions/workflows/ci.yml/badge.svg)](https://github.com/openwisp/django-swappable-models/actions/workflows/ci.yml)
         [![Python 
Support](https://img.shields.io/pypi/pyversions/swapper.svg)](https://pypi.org/project/swapper)
         [![Django 
Support](https://img.shields.io/pypi/djversions/swapper.svg)](https://pypi.org/project/swapper)
         
@@ -57,8 +59,15 @@
         
         Swapper is essentially a simple API wrapper around this existing 
functionality.  Note that Swapper is primarily a tool for library authors; 
users of your reusable app generally should not need to know about Swapper in 
order to use it.  (See the notes on [End User 
Documentation](#end-user-documentation) below.)
         
-        ### Real-World Example
-        Swapper is used extensively in the [vera] extension to [wq.db].  vera 
provides [7 inter-related models], each of which can be swapped out for custom 
implementations.  (Swapper actually started out as part of [wq.db.patterns], 
but was extracted for more general-purpose use.)
+        ### Real-World Examples
+        
+        Swapper is used extensively in several OpenWISP packages to facilitate 
customization and extension.  Notable examples include:
+        
+         * [openwisp-users]
+         * [openwisp-controller]
+         * [openwisp-radius]
+        
+        The use of swapper in these packages promotes [Software 
Reusability][reusability], one of the core values of the OpenWISP project.
         
         ## Creating a Reusable App
         
@@ -118,7 +127,7 @@
         > Note: `swapper.load_model()` is the general equivalent of 
[get_user_model()] and subject to the same constraints: e.g. it should not be 
used until after the model system has fully initialized.
         
         ### Migration Scripts
-        Swapper can also be used in Django 1.7+ migration scripts to 
facilitate dependency ordering and foreign key references.  To use this feature 
in your library, generate a migration script with `makemigrations` and make the 
following changes.  In general, users of your library should not need to make 
any similar changes to their own migration scripts.  The one exception is if 
you have multiple levels of swappable models with foreign keys pointing to each 
other (as in [vera]).
+        Swapper can also be used in migration scripts to facilitate dependency 
ordering and foreign key references.  To use this feature in your library, 
generate a migration script with `makemigrations` and make the following 
changes.  In general, users of your library should not need to make any similar 
changes to their own migration scripts.  The one exception is if you have 
multiple levels of swappable models with foreign keys pointing to each other.
         
         ```diff
           # reusableapp/migrations/0001_initial.py
@@ -199,19 +208,20 @@
         `get_model_name(app_label, model)` | Gets the name of the model the 
swappable model has been swapped for (or the name of the original model if not 
swapped.)
         `get_model_names(app_label, models)` | Match a list of model names to 
their swapped versions.  All of the models should be from the same app (though 
their swapped versions need not be).
         `load_model(app_label, model, required=True)` | Load the swapped model 
class for a swappable model (or the original model if it hasn't been swapped).  
If your code can function without the specified model, set `required = False`.
-        `dependency(app_label, model)` | Generate a dependency tuple for use 
in Django 1.7+ migrations.
-        `set_app_prefix(app_label, prefix)` | Set a custom prefix for 
swappable settings (the default is the upper case `app_label`).  Used in 
[wq.db] to make all of the swappable settings start with `"WQ"` (e.g. 
`WQ_FILE_MODEL` instead of `FILES_FILE_MODEL`).  This should be set at the top 
of your models.py.
+        `dependency(app_label, model, version=None)` | Generate a dependency 
tuple for use in migrations. Use `version` only when depending on the first 
migration of the target dependency doesn't work (eg: when a specific migration 
needs to be depended upon), we recommend avoid using `version='__latest__'` 
because it can have serious [drawbacks] when new migrations are added to the 
module which is being depended upon.
+        `set_app_prefix(app_label, prefix)` | Set a custom prefix for 
swappable settings (the default is the upper case `app_label`).  This can be 
useful if the app has a long name or is part of a larger framework.  This 
should be set at the top of your models.py.
         `join(app_label, model)`, `split(model)` | Utilities for splitting and 
joining `"app.Model"` strings and `("app", "Model")` tuples.
         
         [undocumented]: https://code.djangoproject.com/ticket/19103
-        [swapping the auth.User model]: 
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#auth-custom-user
-        [wq.db]: http://wq.io/wq.db
-        [vera]: http://wq.io/vera
-        [wq.db.patterns]: http://wq.io/docs/about-patterns
-        [7 inter-related models]: https://github.com/wq/vera#models
-        [get_user_model()]: 
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#referencing-the-user-model
-        [#10]: https://github.com/wq/django-swappable-models/issues/10
+        [swapping the auth.User model]: 
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#auth-custom-user
+        [openwisp-users]: 
https://github.com/openwisp/openwisp-users#extend-openwisp-users
+        [openwisp-controller]: 
https://github.com/openwisp/openwisp-controller#extending-openwisp-controller
+        [openwisp-radius]: 
https://openwisp-radius.readthedocs.io/en/latest/developer/how_to_extend.html
+        [reusability]: 
https://openwisp.io/docs/general/values.html#software-reusability-means-long-term-sustainability
+        [get_user_model()]: 
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#referencing-the-user-model
+        [#10]: https://github.com/openwisp/django-swappable-models/issues/10
         [Django ticket #25313]: https://code.djangoproject.com/ticket/25313
+        [drawbacks]: https://code.djangoproject.com/ticket/23071
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
@@ -219,23 +229,16 @@
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Natural Language :: English
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.6
-Classifier: Framework :: Django :: 1.7
-Classifier: Framework :: Django :: 1.8
-Classifier: Framework :: Django :: 1.9
-Classifier: Framework :: Django :: 1.10
-Classifier: Framework :: Django :: 1.11
 Classifier: Framework :: Django :: 2.0
 Classifier: Framework :: Django :: 2.1
 Classifier: Framework :: Django :: 2.2
 Classifier: Framework :: Django :: 3.0
+Classifier: Framework :: Django :: 3.1
+Classifier: Framework :: Django :: 3.2
+Classifier: Framework :: Django :: 4.0
 Description-Content-Type: text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/README.md 
new/swapper-1.3.0/README.md
--- old/swapper-1.1.2.post1/README.md   2019-07-23 04:57:18.000000000 +0200
+++ new/swapper-1.3.0/README.md 2021-11-26 20:23:49.000000000 +0100
@@ -1,6 +1,8 @@
 Swapper
 =======
 
+[![Dependency 
monitoring](https://img.shields.io/librariesio/release/github/openwisp/django-swappable-models)](https://libraries.io/github/openwisp/django-swappable-models)
+
 #### Django Swappable Models - No longer only for auth.User!
 
 Swapper is an unofficial API for the [undocumented] but very powerful Django 
@@ -8,14 +10,14 @@
 arbitrary swappable models in your own reusable apps.
 
 [![Latest PyPI 
Release](https://img.shields.io/pypi/v/swapper.svg)](https://pypi.org/project/swapper)
-[![Release 
Notes](https://img.shields.io/github/release/wq/django-swappable-models.svg
+[![Release 
Notes](https://img.shields.io/github/release/openwisp/django-swappable-models.svg
 )](https://github.com/wq/django-swappable-models/releases)
-[![License](https://img.shields.io/pypi/l/swapper.svg)](https://github.com/wq/django-swappable-models/blob/master/LICENSE)
-[![GitHub 
Stars](https://img.shields.io/github/stars/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/stargazers)
-[![GitHub 
Forks](https://img.shields.io/github/forks/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/network)
-[![GitHub 
Issues](https://img.shields.io/github/issues/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/issues)
+[![License](https://img.shields.io/pypi/l/swapper.svg)](https://github.com/openwisp/django-swappable-models/blob/master/LICENSE)
+[![GitHub 
Stars](https://img.shields.io/github/stars/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/stargazers)
+[![GitHub 
Forks](https://img.shields.io/github/forks/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/network)
+[![GitHub 
Issues](https://img.shields.io/github/issues/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/issues)
 
-[![Travis Build 
Status](https://img.shields.io/travis/wq/django-swappable-models.svg)](https://travis-ci.org/wq/django-swappable-models)
+[![Build 
Status](https://github.com/openwisp/django-swappable-models/actions/workflows/ci.yml/badge.svg)](https://github.com/openwisp/django-swappable-models/actions/workflows/ci.yml)
 [![Python 
Support](https://img.shields.io/pypi/pyversions/swapper.svg)](https://pypi.org/project/swapper)
 [![Django 
Support](https://img.shields.io/pypi/djversions/swapper.svg)](https://pypi.org/project/swapper)
 
@@ -49,8 +51,15 @@
 
 Swapper is essentially a simple API wrapper around this existing 
functionality.  Note that Swapper is primarily a tool for library authors; 
users of your reusable app generally should not need to know about Swapper in 
order to use it.  (See the notes on [End User 
Documentation](#end-user-documentation) below.)
 
-### Real-World Example
-Swapper is used extensively in the [vera] extension to [wq.db].  vera provides 
[7 inter-related models], each of which can be swapped out for custom 
implementations.  (Swapper actually started out as part of [wq.db.patterns], 
but was extracted for more general-purpose use.)
+### Real-World Examples
+
+Swapper is used extensively in several OpenWISP packages to facilitate 
customization and extension.  Notable examples include:
+
+ * [openwisp-users]
+ * [openwisp-controller]
+ * [openwisp-radius]
+
+The use of swapper in these packages promotes [Software 
Reusability][reusability], one of the core values of the OpenWISP project.
 
 ## Creating a Reusable App
 
@@ -110,7 +119,7 @@
 > Note: `swapper.load_model()` is the general equivalent of [get_user_model()] 
 > and subject to the same constraints: e.g. it should not be used until after 
 > the model system has fully initialized.
 
 ### Migration Scripts
-Swapper can also be used in Django 1.7+ migration scripts to facilitate 
dependency ordering and foreign key references.  To use this feature in your 
library, generate a migration script with `makemigrations` and make the 
following changes.  In general, users of your library should not need to make 
any similar changes to their own migration scripts.  The one exception is if 
you have multiple levels of swappable models with foreign keys pointing to each 
other (as in [vera]).
+Swapper can also be used in migration scripts to facilitate dependency 
ordering and foreign key references.  To use this feature in your library, 
generate a migration script with `makemigrations` and make the following 
changes.  In general, users of your library should not need to make any similar 
changes to their own migration scripts.  The one exception is if you have 
multiple levels of swappable models with foreign keys pointing to each other.
 
 ```diff
   # reusableapp/migrations/0001_initial.py
@@ -191,16 +200,17 @@
 `get_model_name(app_label, model)` | Gets the name of the model the swappable 
model has been swapped for (or the name of the original model if not swapped.)
 `get_model_names(app_label, models)` | Match a list of model names to their 
swapped versions.  All of the models should be from the same app (though their 
swapped versions need not be).
 `load_model(app_label, model, required=True)` | Load the swapped model class 
for a swappable model (or the original model if it hasn't been swapped).  If 
your code can function without the specified model, set `required = False`.
-`dependency(app_label, model)` | Generate a dependency tuple for use in Django 
1.7+ migrations.
-`set_app_prefix(app_label, prefix)` | Set a custom prefix for swappable 
settings (the default is the upper case `app_label`).  Used in [wq.db] to make 
all of the swappable settings start with `"WQ"` (e.g. `WQ_FILE_MODEL` instead 
of `FILES_FILE_MODEL`).  This should be set at the top of your models.py.
+`dependency(app_label, model, version=None)` | Generate a dependency tuple for 
use in migrations. Use `version` only when depending on the first migration of 
the target dependency doesn't work (eg: when a specific migration needs to be 
depended upon), we recommend avoid using `version='__latest__'` because it can 
have serious [drawbacks] when new migrations are added to the module which is 
being depended upon.
+`set_app_prefix(app_label, prefix)` | Set a custom prefix for swappable 
settings (the default is the upper case `app_label`).  This can be useful if 
the app has a long name or is part of a larger framework.  This should be set 
at the top of your models.py.
 `join(app_label, model)`, `split(model)` | Utilities for splitting and joining 
`"app.Model"` strings and `("app", "Model")` tuples.
 
 [undocumented]: https://code.djangoproject.com/ticket/19103
-[swapping the auth.User model]: 
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#auth-custom-user
-[wq.db]: http://wq.io/wq.db
-[vera]: http://wq.io/vera
-[wq.db.patterns]: http://wq.io/docs/about-patterns
-[7 inter-related models]: https://github.com/wq/vera#models
-[get_user_model()]: 
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#referencing-the-user-model
-[#10]: https://github.com/wq/django-swappable-models/issues/10
+[swapping the auth.User model]: 
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#auth-custom-user
+[openwisp-users]: 
https://github.com/openwisp/openwisp-users#extend-openwisp-users
+[openwisp-controller]: 
https://github.com/openwisp/openwisp-controller#extending-openwisp-controller
+[openwisp-radius]: 
https://openwisp-radius.readthedocs.io/en/latest/developer/how_to_extend.html
+[reusability]: 
https://openwisp.io/docs/general/values.html#software-reusability-means-long-term-sustainability
+[get_user_model()]: 
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#referencing-the-user-model
+[#10]: https://github.com/openwisp/django-swappable-models/issues/10
 [Django ticket #25313]: https://code.djangoproject.com/ticket/25313
+[drawbacks]: https://code.djangoproject.com/ticket/23071
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/run-qa-checks 
new/swapper-1.3.0/run-qa-checks
--- old/swapper-1.1.2.post1/run-qa-checks       1970-01-01 01:00:00.000000000 
+0100
+++ new/swapper-1.3.0/run-qa-checks     2021-11-12 20:00:49.000000000 +0100
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+openwisp-qa-check \
+       --skip-checkmigrations
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/setup.cfg 
new/swapper-1.3.0/setup.cfg
--- old/swapper-1.1.2.post1/setup.cfg   2020-01-15 02:12:58.000000000 +0100
+++ new/swapper-1.3.0/setup.cfg 2021-11-29 19:51:43.683343000 +0100
@@ -1,3 +1,17 @@
+[bdist_wheel]
+universal = 1
+
+[flake8]
+max-line-length = 110
+ignore = W605, W503, W504
+
+[isort]
+multi_line_output = 3
+use_parentheses = True
+include_trailing_comma = True
+force_grid_wrap = 0
+line_length = 88
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/setup.py 
new/swapper-1.3.0/setup.py
--- old/swapper-1.1.2.post1/setup.py    2020-01-15 02:12:55.000000000 +0100
+++ new/swapper-1.3.0/setup.py  2021-11-12 20:00:49.000000000 +0100
@@ -1,6 +1,4 @@
-import os
-import sys
-from setuptools import setup, find_packages
+from setuptools import setup
 
 LONG_DESCRIPTION = """
 The unofficial Django swappable models API.
@@ -18,10 +16,10 @@
 
 setup(
     name='swapper',
-    version='1.1.2.post1',
+    use_scm_version=True,
     author='S. Andrew Sheppard',
     author_email='[email protected]',
-    url='https://github.com/wq/django-swappable-models',
+    url='https://github.com/openwisp/django-swappable-models',
     license='MIT',
     packages=['swapper'],
     description=LONG_DESCRIPTION.strip(),
@@ -33,29 +31,20 @@
         'License :: OSI Approved :: MIT License',
         'Natural Language :: English',
         'Operating System :: OS Independent',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.4',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
+        'Programming Language :: Python :: 3.9',
         'Framework :: Django',
-        'Framework :: Django :: 1.6',
-        'Framework :: Django :: 1.7',
-        'Framework :: Django :: 1.8',
-        'Framework :: Django :: 1.9',
-        'Framework :: Django :: 1.10',
-        'Framework :: Django :: 1.11',
         'Framework :: Django :: 2.0',
         'Framework :: Django :: 2.1',
         'Framework :: Django :: 2.2',
         'Framework :: Django :: 3.0',
+        'Framework :: Django :: 3.1',
+        'Framework :: Django :: 3.2',
+        'Framework :: Django :: 4.0',
     ],
-    tests_require=['django>=1.6'],
+    tests_require=['django>=2.0'],
     test_suite='tests',
-    setup_requires=[
-        'setuptools_scm',
-    ],
+    setup_requires=['setuptools_scm'],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/swapper/__init__.py 
new/swapper-1.3.0/swapper/__init__.py
--- old/swapper-1.1.2.post1/swapper/__init__.py 2019-07-23 04:57:18.000000000 
+0200
+++ new/swapper-1.3.0/swapper/__init__.py       2021-11-26 20:23:49.000000000 
+0100
@@ -1,6 +1,7 @@
+from django.apps import apps
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
-
+from django.db.migrations import swappable_dependency
 
 _prefixes = {}
 
@@ -11,8 +12,7 @@
     """
     prefix = _prefixes.get(app_label, app_label)
     setting = "{prefix}_{model}_MODEL".format(
-        prefix=prefix.upper(),
-        model=model.upper()
+        prefix=prefix.upper(), model=model.upper()
     )
 
     # Ensure this attribute exists to avoid migration issues in Django 1.7
@@ -44,49 +44,35 @@
     return is_swapped(app_label, model) or join(app_label, model)
 
 
-def dependency(app_label, model):
+def dependency(app_label, model, version=None):
     """
     Returns a Django 1.7+ style dependency tuple for inclusion in
     migration.dependencies[]
     """
-    from django.db.migrations import swappable_dependency
-    return swappable_dependency(get_model_name(app_label, model))
+    dependencies = swappable_dependency(get_model_name(app_label, model))
+    if not version:
+        return dependencies
+    return dependencies[0], version
 
 
 def get_model_names(app_label, models):
     """
     Map model names to their swapped equivalents for the given app
     """
-    return dict(
-        (model, get_model_name(app_label, model))
-        for model in models
-    )
+    return dict((model, get_model_name(app_label, model)) for model in models)
 
 
-def load_model(app_label, model, orm=None, required=True):
+def load_model(app_label, model, required=True, require_ready=True):
     """
     Load the specified model class, or the class it was swapped out for.
-    If a South orm object is provided, it will be used (but only if the
-    model hasn't been swapped.)
     """
     swapped = is_swapped(app_label, model)
     if swapped:
         app_label, model = split(swapped)
-    else:
-        if orm is not None:
-            return orm[join(app_label, model)]
 
     try:
-        try:
-            # django >= 1.7
-            from django.apps import apps
-            cls = apps.get_model(app_label, model)
-        except ImportError:
-            # django < 1.7
-            from django.db.models import get_model
-            cls = get_model(app_label, model)
+        cls = apps.get_model(app_label, model, require_ready=require_ready)
     except LookupError:
-        # both get_model versions can raise a LookupError
         cls = None
 
     if cls is None and required:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/swapper.egg-info/PKG-INFO 
new/swapper-1.3.0/swapper.egg-info/PKG-INFO
--- old/swapper-1.1.2.post1/swapper.egg-info/PKG-INFO   2020-01-15 
02:12:58.000000000 +0100
+++ new/swapper-1.3.0/swapper.egg-info/PKG-INFO 2021-11-29 19:51:43.000000000 
+0100
@@ -1,14 +1,16 @@
 Metadata-Version: 2.1
 Name: swapper
-Version: 1.1.2.post1
+Version: 1.3.0
 Summary: The unofficial Django swappable models API.
-Home-page: https://github.com/wq/django-swappable-models
+Home-page: https://github.com/openwisp/django-swappable-models
 Author: S. Andrew Sheppard
 Author-email: [email protected]
 License: MIT
 Description: Swapper
         =======
         
+        [![Dependency 
monitoring](https://img.shields.io/librariesio/release/github/openwisp/django-swappable-models)](https://libraries.io/github/openwisp/django-swappable-models)
+        
         #### Django Swappable Models - No longer only for auth.User!
         
         Swapper is an unofficial API for the [undocumented] but very powerful 
Django 
@@ -16,14 +18,14 @@
         arbitrary swappable models in your own reusable apps.
         
         [![Latest PyPI 
Release](https://img.shields.io/pypi/v/swapper.svg)](https://pypi.org/project/swapper)
-        [![Release 
Notes](https://img.shields.io/github/release/wq/django-swappable-models.svg
+        [![Release 
Notes](https://img.shields.io/github/release/openwisp/django-swappable-models.svg
         )](https://github.com/wq/django-swappable-models/releases)
-        
[![License](https://img.shields.io/pypi/l/swapper.svg)](https://github.com/wq/django-swappable-models/blob/master/LICENSE)
-        [![GitHub 
Stars](https://img.shields.io/github/stars/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/stargazers)
-        [![GitHub 
Forks](https://img.shields.io/github/forks/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/network)
-        [![GitHub 
Issues](https://img.shields.io/github/issues/wq/django-swappable-models.svg)](https://github.com/wq/django-swappable-models/issues)
+        
[![License](https://img.shields.io/pypi/l/swapper.svg)](https://github.com/openwisp/django-swappable-models/blob/master/LICENSE)
+        [![GitHub 
Stars](https://img.shields.io/github/stars/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/stargazers)
+        [![GitHub 
Forks](https://img.shields.io/github/forks/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/network)
+        [![GitHub 
Issues](https://img.shields.io/github/issues/openwisp/django-swappable-models.svg)](https://github.com/openwisp/django-swappable-models/issues)
         
-        [![Travis Build 
Status](https://img.shields.io/travis/wq/django-swappable-models.svg)](https://travis-ci.org/wq/django-swappable-models)
+        [![Build 
Status](https://github.com/openwisp/django-swappable-models/actions/workflows/ci.yml/badge.svg)](https://github.com/openwisp/django-swappable-models/actions/workflows/ci.yml)
         [![Python 
Support](https://img.shields.io/pypi/pyversions/swapper.svg)](https://pypi.org/project/swapper)
         [![Django 
Support](https://img.shields.io/pypi/djversions/swapper.svg)](https://pypi.org/project/swapper)
         
@@ -57,8 +59,15 @@
         
         Swapper is essentially a simple API wrapper around this existing 
functionality.  Note that Swapper is primarily a tool for library authors; 
users of your reusable app generally should not need to know about Swapper in 
order to use it.  (See the notes on [End User 
Documentation](#end-user-documentation) below.)
         
-        ### Real-World Example
-        Swapper is used extensively in the [vera] extension to [wq.db].  vera 
provides [7 inter-related models], each of which can be swapped out for custom 
implementations.  (Swapper actually started out as part of [wq.db.patterns], 
but was extracted for more general-purpose use.)
+        ### Real-World Examples
+        
+        Swapper is used extensively in several OpenWISP packages to facilitate 
customization and extension.  Notable examples include:
+        
+         * [openwisp-users]
+         * [openwisp-controller]
+         * [openwisp-radius]
+        
+        The use of swapper in these packages promotes [Software 
Reusability][reusability], one of the core values of the OpenWISP project.
         
         ## Creating a Reusable App
         
@@ -118,7 +127,7 @@
         > Note: `swapper.load_model()` is the general equivalent of 
[get_user_model()] and subject to the same constraints: e.g. it should not be 
used until after the model system has fully initialized.
         
         ### Migration Scripts
-        Swapper can also be used in Django 1.7+ migration scripts to 
facilitate dependency ordering and foreign key references.  To use this feature 
in your library, generate a migration script with `makemigrations` and make the 
following changes.  In general, users of your library should not need to make 
any similar changes to their own migration scripts.  The one exception is if 
you have multiple levels of swappable models with foreign keys pointing to each 
other (as in [vera]).
+        Swapper can also be used in migration scripts to facilitate dependency 
ordering and foreign key references.  To use this feature in your library, 
generate a migration script with `makemigrations` and make the following 
changes.  In general, users of your library should not need to make any similar 
changes to their own migration scripts.  The one exception is if you have 
multiple levels of swappable models with foreign keys pointing to each other.
         
         ```diff
           # reusableapp/migrations/0001_initial.py
@@ -199,19 +208,20 @@
         `get_model_name(app_label, model)` | Gets the name of the model the 
swappable model has been swapped for (or the name of the original model if not 
swapped.)
         `get_model_names(app_label, models)` | Match a list of model names to 
their swapped versions.  All of the models should be from the same app (though 
their swapped versions need not be).
         `load_model(app_label, model, required=True)` | Load the swapped model 
class for a swappable model (or the original model if it hasn't been swapped).  
If your code can function without the specified model, set `required = False`.
-        `dependency(app_label, model)` | Generate a dependency tuple for use 
in Django 1.7+ migrations.
-        `set_app_prefix(app_label, prefix)` | Set a custom prefix for 
swappable settings (the default is the upper case `app_label`).  Used in 
[wq.db] to make all of the swappable settings start with `"WQ"` (e.g. 
`WQ_FILE_MODEL` instead of `FILES_FILE_MODEL`).  This should be set at the top 
of your models.py.
+        `dependency(app_label, model, version=None)` | Generate a dependency 
tuple for use in migrations. Use `version` only when depending on the first 
migration of the target dependency doesn't work (eg: when a specific migration 
needs to be depended upon), we recommend avoid using `version='__latest__'` 
because it can have serious [drawbacks] when new migrations are added to the 
module which is being depended upon.
+        `set_app_prefix(app_label, prefix)` | Set a custom prefix for 
swappable settings (the default is the upper case `app_label`).  This can be 
useful if the app has a long name or is part of a larger framework.  This 
should be set at the top of your models.py.
         `join(app_label, model)`, `split(model)` | Utilities for splitting and 
joining `"app.Model"` strings and `("app", "Model")` tuples.
         
         [undocumented]: https://code.djangoproject.com/ticket/19103
-        [swapping the auth.User model]: 
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#auth-custom-user
-        [wq.db]: http://wq.io/wq.db
-        [vera]: http://wq.io/vera
-        [wq.db.patterns]: http://wq.io/docs/about-patterns
-        [7 inter-related models]: https://github.com/wq/vera#models
-        [get_user_model()]: 
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#referencing-the-user-model
-        [#10]: https://github.com/wq/django-swappable-models/issues/10
+        [swapping the auth.User model]: 
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#auth-custom-user
+        [openwisp-users]: 
https://github.com/openwisp/openwisp-users#extend-openwisp-users
+        [openwisp-controller]: 
https://github.com/openwisp/openwisp-controller#extending-openwisp-controller
+        [openwisp-radius]: 
https://openwisp-radius.readthedocs.io/en/latest/developer/how_to_extend.html
+        [reusability]: 
https://openwisp.io/docs/general/values.html#software-reusability-means-long-term-sustainability
+        [get_user_model()]: 
https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#referencing-the-user-model
+        [#10]: https://github.com/openwisp/django-swappable-models/issues/10
         [Django ticket #25313]: https://code.djangoproject.com/ticket/25313
+        [drawbacks]: https://code.djangoproject.com/ticket/23071
         
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
@@ -219,23 +229,16 @@
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Natural Language :: English
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.6
-Classifier: Framework :: Django :: 1.7
-Classifier: Framework :: Django :: 1.8
-Classifier: Framework :: Django :: 1.9
-Classifier: Framework :: Django :: 1.10
-Classifier: Framework :: Django :: 1.11
 Classifier: Framework :: Django :: 2.0
 Classifier: Framework :: Django :: 2.1
 Classifier: Framework :: Django :: 2.2
 Classifier: Framework :: Django :: 3.0
+Classifier: Framework :: Django :: 3.1
+Classifier: Framework :: Django :: 3.2
+Classifier: Framework :: Django :: 4.0
 Description-Content-Type: text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/swapper.egg-info/SOURCES.txt 
new/swapper-1.3.0/swapper.egg-info/SOURCES.txt
--- old/swapper-1.1.2.post1/swapper.egg-info/SOURCES.txt        2020-01-15 
02:12:58.000000000 +0100
+++ new/swapper-1.3.0/swapper.egg-info/SOURCES.txt      2021-11-29 
19:51:43.000000000 +0100
@@ -1,9 +1,12 @@
 .gitignore
-.travis.yml
+CHANGES.rst
 LICENSE
 README.md
+run-qa-checks
+setup.cfg
 setup.py
 tox.ini
+.github/workflows/ci.yml
 swapper/__init__.py
 swapper.egg-info/PKG-INFO
 swapper.egg-info/SOURCES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/tests/__init__.py 
new/swapper-1.3.0/tests/__init__.py
--- old/swapper-1.1.2.post1/tests/__init__.py   2019-07-23 04:57:18.000000000 
+0200
+++ new/swapper-1.3.0/tests/__init__.py 2021-11-12 20:00:49.000000000 +0100
@@ -1,7 +1,8 @@
 import os
-from django.test.utils import setup_test_environment
-from django.core.management import call_command
+
 import django
+from django.core.management import call_command
+from django.test.utils import setup_test_environment
 
 os.environ.setdefault('DJANGO_SETTINGS_MODULE', "tests.settings")
 setup_test_environment()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/tests/alt_app/models.py 
new/swapper-1.3.0/tests/alt_app/models.py
--- old/swapper-1.1.2.post1/tests/alt_app/models.py     2015-11-16 
21:33:10.000000000 +0100
+++ new/swapper-1.3.0/tests/alt_app/models.py   2021-11-12 20:00:49.000000000 
+0100
@@ -1,4 +1,5 @@
 from django.db import models
+
 from tests.default_app.models import BaseType
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/tests/default_app/models.py 
new/swapper-1.3.0/tests/default_app/models.py
--- old/swapper-1.1.2.post1/tests/default_app/models.py 2019-07-23 
04:57:18.000000000 +0200
+++ new/swapper-1.3.0/tests/default_app/models.py       2021-11-12 
20:00:49.000000000 +0100
@@ -1,4 +1,5 @@
 from django.db import models
+
 import swapper
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/tests/settings.py 
new/swapper-1.3.0/tests/settings.py
--- old/swapper-1.1.2.post1/tests/settings.py   2015-11-16 21:33:10.000000000 
+0100
+++ new/swapper-1.3.0/tests/settings.py 2021-11-12 20:00:49.000000000 +0100
@@ -1,12 +1,7 @@
 SECRET_KEY = '1234'
-INSTALLED_APPS = (
-    'tests.default_app',
-)
+INSTALLED_APPS = ('tests.default_app',)
 MIDDLEWARE_CLASSES = tuple()
 DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.sqlite3',
-        'NAME': ':memory:',
-    }
+    'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'},
 }
 SWAP = False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/tests/swap_settings.py 
new/swapper-1.3.0/tests/swap_settings.py
--- old/swapper-1.1.2.post1/tests/swap_settings.py      2019-07-23 
04:57:18.000000000 +0200
+++ new/swapper-1.3.0/tests/swap_settings.py    2021-11-12 20:00:49.000000000 
+0100
@@ -1,9 +1,9 @@
-from .settings import (  # noqa
-    SECRET_KEY,
-    INSTALLED_APPS,
-    MIDDLEWARE_CLASSES,
-    DATABASES,
-)
-INSTALLED_APPS += ('tests.alt_app',)
+from . import settings
+
 DEFAULT_APP_TYPE_MODEL = "alt_app.Type"
+MIDDLEWARE_CLASSES = settings.MIDDLEWARE_CLASSES
+DATABASES = settings.DATABASES
+INSTALLED_APPS = settings.INSTALLED_APPS
+INSTALLED_APPS += ('tests.alt_app',)
+SECRET_KEY = settings.SECRET_KEY
 SWAP = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/tests/test_swapper.py 
new/swapper-1.3.0/tests/test_swapper.py
--- old/swapper-1.1.2.post1/tests/test_swapper.py       2019-07-23 
04:57:18.000000000 +0200
+++ new/swapper-1.3.0/tests/test_swapper.py     2021-11-26 20:23:49.000000000 
+0100
@@ -1,10 +1,10 @@
-from django.test import TestCase
-import swapper
+import unittest
+
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
+from django.test import TestCase
 
-
-import unittest
+import swapper
 
 try:
     from django.db import migrations  # noqa
@@ -19,10 +19,7 @@
     # Tests that should work whether or not default_app.Type is swapped
     def test_fields(self):
         Type = swapper.load_model('default_app', 'Type')
-        fields = dict(
-            (field.name, field)
-            for field in Type._meta.fields
-        )
+        fields = dict((field.name, field) for field in Type._meta.fields)
         self.assertIn('name', fields)
 
     def test_create(self):
@@ -51,24 +48,19 @@
     def test_contrib_app_split(self):
         self.assertEqual(
             swapper.split('alt_app.contrib.named_things.NamedThing'),
-            ('alt_app.contrib.named_things', 'NamedThing'))
+            ('alt_app.contrib.named_things', 'NamedThing'),
+        )
 
     # Tests that only work if default_app.Type is swapped
     @unittest.skipUnless(settings.SWAP, "requires swapped models")
     def test_swap_setting(self):
         self.assertTrue(swapper.is_swapped("default_app", "Type"))
-        self.assertEqual(
-            swapper.get_model_name("default_app", "Type"),
-            "alt_app.Type"
-        )
+        self.assertEqual(swapper.get_model_name("default_app", "Type"), 
"alt_app.Type")
 
     @unittest.skipUnless(settings.SWAP, "requires swapped models")
     def test_swap_fields(self):
         Type = swapper.load_model('default_app', 'Type')
-        fields = dict(
-            (field.name, field)
-            for field in Type._meta.fields
-        )
+        fields = dict((field.name, field) for field in Type._meta.fields)
         self.assertIn('code', fields)
 
     @unittest.skipUnless(settings.SWAP, "requires swapped models")
@@ -88,14 +80,18 @@
         item = Item.objects.all()[0]
         self.assertEqual(item.type.code, "type-1")
 
-    @unittest.skipUnless(
-        settings.SWAP and DJ17,
-        "requires swapped models & Django 1.7"
-    )
+    @unittest.skipUnless(settings.SWAP and DJ17, "requires swapped models & 
Django 1.7")
     def test_swap_dependency(self):
         self.assertEqual(
-            swapper.dependency("default_app", "Type"),
-            ("alt_app", "__first__")
+            swapper.dependency("default_app", "Type"), ("alt_app", "__first__")
+        )
+        self.assertEqual(
+            swapper.dependency("default_app", "Type", "__latest__"),
+            ("alt_app", "__latest__"),
+        )
+        self.assertEqual(
+            swapper.dependency("default_app", "Type", "0001_custom_migration"),
+            ("alt_app", "0001_custom_migration"),
         )
 
     # Tests that only work if default_app.Type is *not* swapped
@@ -103,16 +99,14 @@
     def test_default_setting(self):
         self.assertFalse(swapper.is_swapped("default_app", "Type"))
         self.assertEqual(
-            swapper.get_model_name("default_app", "Type"),
-            "default_app.Type"
+            swapper.get_model_name("default_app", "Type"), "default_app.Type"
         )
 
     @unittest.skipUnless(
-        not settings.SWAP and DJ17,
-        "requires non-swapped models & Django 1.7"
+        not settings.SWAP and DJ17, "requires non-swapped models & Django 1.7"
     )
     def test_default_dependency(self):
         self.assertEqual(
             swapper.dependency("default_app", "Type"),
-            ("default_app", "__first__")
+            ("default_app", "__first__"),
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/swapper-1.1.2.post1/tox.ini new/swapper-1.3.0/tox.ini
--- old/swapper-1.1.2.post1/tox.ini     2020-01-15 02:07:09.000000000 +0100
+++ new/swapper-1.3.0/tox.ini   2021-11-12 20:00:49.000000000 +0100
@@ -1,40 +1,28 @@
 [tox]
 envlist =
-    py{27}-django16-{noswap,swap}
-    py{27,34}-django17-{noswap,swap}
-    py{27,34,35}-django18-{noswap,swap}
-    py{27,34,35}-django19-{noswap,swap}
-    py{27,34,35}-django110-{noswap,swap}
-    py{27,34,35,36,37}-django111-{noswap,swap}
-    py{34,35,36,37}-django20-{noswap,swap}
-    py{35,36,37,38}-django21-{noswap,swap}
-    py{35,36,37,38}-django22-{noswap,swap}
-    py{36,37,38}-django30-{noswap,swap}
+    py{37,38}-django22-{noswap,swap}
+    py{37,38}-django30-{noswap,swap}
+    py{37,38,39}-django31-{noswap,swap}
+    py{37,38,39}-django32-{noswap,swap}
+    py{38,39}-django40-{noswap, swap}
     lint
 
-[tox:travis]
-2.7 = py27
-3.4 = py34
-3.5 = py35
-3.6 = py36
-3.7 = py37
-3.8 = py38, lint
+[gh-actions]
+python =
+    3.7: py37
+    3.8: py38, lint
+    3.9: py39, lint
 
 [testenv]
 commands =
     rm -rf tests/default_app/migrations/ tests/alt_app/migrations/
     python setup.py test
 deps =
-    django16: django~=1.6.0
-    django17: django~=1.7.0
-    django18: django~=1.8.0
-    django19: django~=1.9.0
-    django110: django~=1.10.0
-    django111: django~=1.11.0
-    django20: django~=2.0.0
-    django21: django~=2.1.0
     django22: django~=2.2.0
     django30: django~=3.0.0
+    django31: django~=3.1.0
+    django32: django~=3.2.0
+    django40: django~=4.0a1
 setenv =
     noswap: DJANGO_SETTINGS_MODULE=tests.settings
     swap: DJANGO_SETTINGS_MODULE=tests.swap_settings

Reply via email to