Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-django-auth-ldap for 
openSUSE:Factory checked in at 2022-02-22 21:18:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-auth-ldap (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-auth-ldap.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-auth-ldap"

Tue Feb 22 21:18:06 2022 rev:16 rq:956492 version:4.0.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-auth-ldap/python-django-auth-ldap.changes
  2020-06-10 00:50:56.371341064 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-django-auth-ldap.new.1958/python-django-auth-ldap.changes
        2022-02-22 21:18:38.106291124 +0100
@@ -1,0 +2,21 @@
+Mon Feb 21 13:38:55 UTC 2022 - John Vandenberg <[email protected]>
+
+- Use fdupes
+- Update to v4.0.0
+  * The signal ldap_error now has an additional `request` keyword.
+  * Added support for Python 3.10.
+  * Added support for Django 4.0.
+- from v3.0.0
+  * Dropped support for Django 3.0.
+  * Dropped deprecated setting ``AUTH_LDAP_CACHE_GROUPS``.
+  * Callables passed to ``AUTH_LDAP_SERVER_URI`` must now take a
+    ``request`` positional argument.
+- from v2.4.0
+  * Added support for Django 3.2.
+- from v2.3.0
+  * Removed support for end of life Django 1.11. Django 2.2+ reqd.
+  * Removed support for end of life Python 3.5.
+  * Added support for Django 3.1.
+  * Added support for Python 3.9.
+
+-------------------------------------------------------------------

Old:
----
  django-auth-ldap-2.2.0.tar.gz

New:
----
  django-auth-ldap-4.0.0.tar.gz

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

Other differences:
------------------
++++++ python-django-auth-ldap.spec ++++++
--- /var/tmp/diff_new_pack.HudbuX/_old  2022-02-22 21:18:39.850291444 +0100
+++ /var/tmp/diff_new_pack.HudbuX/_new  2022-02-22 21:18:39.858291445 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-django-auth-ldap
 #
-# 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
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-django-auth-ldap
-Version:        2.2.0
+Version:        4.0.0
 Release:        0
 Summary:        Django LDAP authentication backend
 License:        BSD-2-Clause
@@ -27,8 +27,9 @@
 Source:         
https://files.pythonhosted.org/packages/source/d/django-auth-ldap/django-auth-ldap-%{version}.tar.gz
 BuildRequires:  %{python_module Django >= 2.2}
 BuildRequires:  %{python_module ldap >= 3.1}
-BuildRequires:  %{python_module mock >= 2.0.0}
-BuildRequires:  %{python_module setuptools}
+BuildRequires:  %{python_module pip}
+BuildRequires:  %{python_module wheel}
+BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 # needed for slapd binary in tests
 BuildRequires:  openldap2
@@ -48,14 +49,16 @@
 %setup -q -n django-auth-ldap-%{version}
 
 %build
-%python_build
+%pyproject_wheel
 
 %install
-%python_install
+%pyproject_install
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
 export LANG=en_US.UTF8
-%python_exec -m django test --settings tests.settings
+export PATH=/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/bin 
+%python_exec -m django test --settings tests.settings -v2
 
 %files %{python_files}
 %license LICENSE

++++++ django-auth-ldap-2.2.0.tar.gz -> django-auth-ldap-4.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/CHANGES 
new/django-auth-ldap-4.0.0/CHANGES
--- old/django-auth-ldap-2.2.0/CHANGES  2020-06-03 01:45:40.000000000 +0200
+++ new/django-auth-ldap-4.0.0/CHANGES  2021-12-16 13:13:34.000000000 +0100
@@ -1,3 +1,40 @@
+UNRELEASED
+----------
+
+Breaking changes
+^^^^^^^^^^^^^^^^
+
+- The signal ``ldap_error`` now has an additional ``request`` keyword argument.
+
+- Added support for Python 3.10.
+- Added support for Django 4.0.
+
+3.0.0 ??? 2021-07-19
+------------------
+
+- Dropped support for Django 3.0.
+
+Breaking changes
+^^^^^^^^^^^^^^^^
+
+- Dropped deprecated setting ``AUTH_LDAP_CACHE_GROUPS``.
+- Callables passed to ``AUTH_LDAP_SERVER_URI`` must now take a ``request`` 
positional argument.
+
+2.4.0 - 2021-04-06
+------------------
+
+- Added support for Django 3.2.
+
+2.3.0 - 2021-02-15
+------------------
+
+- Removed support for end of life Django 1.11. django-auth-ldap now requires
+  Django 2.2+.
+- Removed support for end of life Python 3.5.
+- Added support for Django 3.1.
+- Added support for Python 3.9.
+- Removed ``dev-requirements.txt`` in favor of :doc:`tox <tox:index>`.
+
 2.2.0 - 2020-06-02
 ------------------
 
@@ -12,7 +49,7 @@
 
 - Reject authentication requests without a username.
 - Added support for Django 3.0 and Python 3.8.
-- Removed support for Django end of life Django 2.1.
+- Removed support for end of life Django 2.1.
 
 2.0.0 - 2019-06-05
 ------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/MANIFEST.in 
new/django-auth-ldap-4.0.0/MANIFEST.in
--- old/django-auth-ldap-2.2.0/MANIFEST.in      2019-10-28 00:55:24.000000000 
+0100
+++ new/django-auth-ldap-4.0.0/MANIFEST.in      2021-05-05 15:49:26.000000000 
+0200
@@ -1,6 +1,2 @@
-include README.md LICENSE CHANGES
-include tox.ini
-
-recursive-include docs *
-recursive-include tests *
-prune docs/build
+exclude .editorconfig .gitignore .readthedocs.yml
+prune .github
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/PKG-INFO 
new/django-auth-ldap-4.0.0/PKG-INFO
--- old/django-auth-ldap-2.2.0/PKG-INFO 2020-06-03 01:49:56.901470400 +0200
+++ new/django-auth-ldap-4.0.0/PKG-INFO 2021-12-16 15:17:23.931323800 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
 Name: django-auth-ldap
-Version: 2.2.0
+Version: 4.0.0
 Summary: Django LDAP authentication backend.
 Home-page: https://github.com/django-auth-ldap/django-auth-ldap
 Author: Peter Sagerson
@@ -9,189 +9,193 @@
 Project-URL: Documentation, https://django-auth-ldap.readthedocs.io/
 Project-URL: Source, https://github.com/django-auth-ldap/django-auth-ldap
 Project-URL: Tracker, 
https://github.com/django-auth-ldap/django-auth-ldap/issues
-Description: ================================
-        Django Authentication Using LDAP
-        ================================
-        
-        .. image:: 
https://readthedocs.org/projects/django-auth-ldap/badge/?version=latest
-           :target: https://django-auth-ldap.readthedocs.io/en/latest/
-        
-        .. image:: https://img.shields.io/pypi/v/django-auth-ldap.svg
-           :target: https://pypi.org/project/django-auth-ldap/
-        
-        .. image:: 
https://img.shields.io/travis/django-auth-ldap/django-auth-ldap/master.svg?label=travis-ci
-           :target: http://travis-ci.org/django-auth-ldap/django-auth-ldap
-        
-        .. image:: https://img.shields.io/pypi/l/django-auth-ldap.svg
-           :target: 
https://raw.githubusercontent.com/django-auth-ldap/django-auth-ldap/master/LICENSE
-        
-        This is a Django authentication backend that authenticates against an 
LDAP
-        service. Configuration can be as simple as a single distinguished name
-        template, but there are many rich configuration options for working 
with users,
-        groups, and permissions.
-        
-        * Documentation: https://django-auth-ldap.readthedocs.io/
-        * PyPI: https://pypi.org/project/django-auth-ldap/
-        * Repository: https://github.com/django-auth-ldap/django-auth-ldap
-        * Tests: http://travis-ci.org/django-auth-ldap/django-auth-ldap
-        * License: BSD 2-Clause
-        
-        This version is supported on Python 3.5+; and Django 1.11+. It requires
-        `python-ldap`_ >= 3.1.
-        
-        .. _`python-ldap`: https://pypi.org/project/python-ldap/
-        
-        
-        Installation
-        ============
-        
-        Install the package with pip:
-        
-        .. code-block:: sh
-        
-            $ pip install django-auth-ldap
-        
-        It requires `python-ldap`_ >= 3.1. You'll need the `OpenLDAP`_ 
libraries and
-        headers available on your system.
-        
-        To use the auth backend in a Django project, add
-        ``'django_auth_ldap.backend.LDAPBackend'`` to 
``AUTHENTICATION_BACKENDS``. Do
-        not add anything to ``INSTALLED_APPS``.
-        
-        .. code-block:: python
-        
-            AUTHENTICATION_BACKENDS = [
-                'django_auth_ldap.backend.LDAPBackend',
-            ]
-        
-        ``LDAPBackend`` should work with custom user models, but it does 
assume that a
-        database is present.
-        
-        .. note::
-        
-            ``LDAPBackend`` does not inherit from ``ModelBackend``. It is 
possible to
-            use ``LDAPBackend`` exclusively by configuring it to draw group 
membership
-            from the LDAP server. However, if you would like to assign 
permissions to
-            individual users or add users to groups within Django, you'll need 
to have
-            both backends installed:
-        
-            .. code-block:: python
-        
-                AUTHENTICATION_BACKENDS = [
-                    'django_auth_ldap.backend.LDAPBackend',
-                    'django.contrib.auth.backends.ModelBackend',
-                ]
-        
-        .. _`python-ldap`: https://pypi.org/project/python-ldap/
-        .. _`OpenLDAP`: https://www.openldap.org/
-        
-        
-        Example Configuration
-        =====================
-        
-        Here is a complete example configuration from ``settings.py`` that 
exercises
-        nearly all of the features. In this example, we're authenticating 
against a
-        global pool of users in the directory, but we have a special area set 
aside for
-        Django groups (``ou=django,ou=groups,dc=example,dc=com``). Remember 
that most
-        of this is optional if you just need simple authentication. Some 
default
-        settings and arguments are included for completeness.
-        
-        .. code-block:: python
-        
-            import ldap
-            from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
-        
-        
-            # Baseline configuration.
-            AUTH_LDAP_SERVER_URI = 'ldap://ldap.example.com'
-        
-            AUTH_LDAP_BIND_DN = 'cn=django-agent,dc=example,dc=com'
-            AUTH_LDAP_BIND_PASSWORD = 'phlebotinum'
-            AUTH_LDAP_USER_SEARCH = LDAPSearch(
-                'ou=users,dc=example,dc=com',
-                ldap.SCOPE_SUBTREE,
-                '(uid=%(user)s)',
-            )
-            # Or:
-            # AUTH_LDAP_USER_DN_TEMPLATE = 
'uid=%(user)s,ou=users,dc=example,dc=com'
-        
-            # Set up the basic group parameters.
-            AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
-                'ou=django,ou=groups,dc=example,dc=com',
-                ldap.SCOPE_SUBTREE,
-                '(objectClass=groupOfNames)',
-            )
-            AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr='cn')
-        
-            # Simple group restrictions
-            AUTH_LDAP_REQUIRE_GROUP = 
'cn=enabled,ou=django,ou=groups,dc=example,dc=com'
-            AUTH_LDAP_DENY_GROUP = 
'cn=disabled,ou=django,ou=groups,dc=example,dc=com'
-        
-            # Populate the Django user from the LDAP directory.
-            AUTH_LDAP_USER_ATTR_MAP = {
-                'first_name': 'givenName',
-                'last_name': 'sn',
-                'email': 'mail',
-            }
-        
-            AUTH_LDAP_USER_FLAGS_BY_GROUP = {
-                'is_active': 'cn=active,ou=django,ou=groups,dc=example,dc=com',
-                'is_staff': 'cn=staff,ou=django,ou=groups,dc=example,dc=com',
-                'is_superuser': 
'cn=superuser,ou=django,ou=groups,dc=example,dc=com',
-            }
-        
-            # This is the default, but I like to be explicit.
-            AUTH_LDAP_ALWAYS_UPDATE_USER = True
-        
-            # Use LDAP group membership to calculate group permissions.
-            AUTH_LDAP_FIND_GROUP_PERMS = True
-        
-            # Cache distinguished names and group memberships for an hour to 
minimize
-            # LDAP traffic.
-            AUTH_LDAP_CACHE_TIMEOUT = 3600
-        
-            # Keep ModelBackend around for per-user permissions and maybe a 
local
-            # superuser.
-            AUTHENTICATION_BACKENDS = (
-                'django_auth_ldap.backend.LDAPBackend',
-                'django.contrib.auth.backends.ModelBackend',
-            )
-        
-        
-        Contributing
-        ============
-        
-        If you'd like to contribute, the best approach is to send a 
well-formed pull
-        request, complete with tests and documentation. Pull requests should be
-        focused: trying to do more than one thing in a single request will 
make it more
-        difficult to process.
-        
-        If you have a bug or feature request you can try `logging an issue`_.
-        
-        There's no harm in creating an issue and then submitting a pull 
request to
-        resolve it. This can be a good way to start a conversation and can 
serve as an
-        anchor point.
-        
-        .. _`logging an issue`: 
https://github.com/django-auth-ldap/django-auth-ldap/issues
-        
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.11
 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
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: System Administrators
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3 :: Only
-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: Programming Language :: Python :: 3.10
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Topic :: System :: Systems Administration :: 
Authentication/Directory :: LDAP
-Requires-Python: >=3.5
+Requires-Python: >=3.6
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+
+================================
+Django Authentication Using LDAP
+================================
+
+.. image:: 
https://readthedocs.org/projects/django-auth-ldap/badge/?version=latest
+   :target: https://django-auth-ldap.readthedocs.io/en/latest/
+
+.. image:: https://img.shields.io/pypi/v/django-auth-ldap.svg
+   :target: https://pypi.org/project/django-auth-ldap/
+
+.. image:: 
https://github.com/django-auth-ldap/django-auth-ldap/workflows/Test/badge.svg
+   :target: 
https://github.com/django-auth-ldap/django-auth-ldap/workflows/Test/badge.svg
+
+.. image:: https://img.shields.io/pypi/l/django-auth-ldap.svg
+   :target: 
https://raw.githubusercontent.com/django-auth-ldap/django-auth-ldap/master/LICENSE
+
+This is a Django authentication backend that authenticates against an LDAP
+service. Configuration can be as simple as a single distinguished name
+template, but there are many rich configuration options for working with users,
+groups, and permissions.
+
+* Documentation: https://django-auth-ldap.readthedocs.io/
+* PyPI: https://pypi.org/project/django-auth-ldap/
+* Repository: https://github.com/django-auth-ldap/django-auth-ldap
+* License: BSD 2-Clause
+
+This version is supported on Python 3.6+; and Django 2.2+. It requires
+`python-ldap`_ >= 3.1.
+
+.. _`python-ldap`: https://pypi.org/project/python-ldap/
+
+
+Installation
+============
+
+Install the package with pip:
+
+.. code-block:: sh
+
+    $ pip install django-auth-ldap
+
+It requires `python-ldap`_ >= 3.1. You'll need the `OpenLDAP`_ libraries and
+headers available on your system.
+
+To use the auth backend in a Django project, add
+``'django_auth_ldap.backend.LDAPBackend'`` to ``AUTHENTICATION_BACKENDS``. Do
+not add anything to ``INSTALLED_APPS``.
+
+.. code-block:: python
+
+    AUTHENTICATION_BACKENDS = [
+        'django_auth_ldap.backend.LDAPBackend',
+    ]
+
+``LDAPBackend`` should work with custom user models, but it does assume that a
+database is present.
+
+.. note::
+
+    ``LDAPBackend`` does not inherit from ``ModelBackend``. It is possible to
+    use ``LDAPBackend`` exclusively by configuring it to draw group membership
+    from the LDAP server. However, if you would like to assign permissions to
+    individual users or add users to groups within Django, you'll need to have
+    both backends installed:
+
+    .. code-block:: python
+
+        AUTHENTICATION_BACKENDS = [
+            'django_auth_ldap.backend.LDAPBackend',
+            'django.contrib.auth.backends.ModelBackend',
+        ]
+
+.. _`OpenLDAP`: https://www.openldap.org/
+
+
+Example Configuration
+=====================
+
+Here is a complete example configuration from ``settings.py`` that exercises
+nearly all of the features. In this example, we're authenticating against a
+global pool of users in the directory, but we have a special area set aside for
+Django groups (``ou=django,ou=groups,dc=example,dc=com``). Remember that most
+of this is optional if you just need simple authentication. Some default
+settings and arguments are included for completeness.
+
+.. code-block:: python
+
+    import ldap
+    from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
+
+
+    # Baseline configuration.
+    AUTH_LDAP_SERVER_URI = 'ldap://ldap.example.com'
+
+    AUTH_LDAP_BIND_DN = 'cn=django-agent,dc=example,dc=com'
+    AUTH_LDAP_BIND_PASSWORD = 'phlebotinum'
+    AUTH_LDAP_USER_SEARCH = LDAPSearch(
+        'ou=users,dc=example,dc=com',
+        ldap.SCOPE_SUBTREE,
+        '(uid=%(user)s)',
+    )
+    # Or:
+    # AUTH_LDAP_USER_DN_TEMPLATE = 'uid=%(user)s,ou=users,dc=example,dc=com'
+
+    # Set up the basic group parameters.
+    AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
+        'ou=django,ou=groups,dc=example,dc=com',
+        ldap.SCOPE_SUBTREE,
+        '(objectClass=groupOfNames)',
+    )
+    AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr='cn')
+
+    # Simple group restrictions
+    AUTH_LDAP_REQUIRE_GROUP = 
'cn=enabled,ou=django,ou=groups,dc=example,dc=com'
+    AUTH_LDAP_DENY_GROUP = 'cn=disabled,ou=django,ou=groups,dc=example,dc=com'
+
+    # Populate the Django user from the LDAP directory.
+    AUTH_LDAP_USER_ATTR_MAP = {
+        'first_name': 'givenName',
+        'last_name': 'sn',
+        'email': 'mail',
+    }
+
+    AUTH_LDAP_USER_FLAGS_BY_GROUP = {
+        'is_active': 'cn=active,ou=django,ou=groups,dc=example,dc=com',
+        'is_staff': 'cn=staff,ou=django,ou=groups,dc=example,dc=com',
+        'is_superuser': 'cn=superuser,ou=django,ou=groups,dc=example,dc=com',
+    }
+
+    # This is the default, but I like to be explicit.
+    AUTH_LDAP_ALWAYS_UPDATE_USER = True
+
+    # Use LDAP group membership to calculate group permissions.
+    AUTH_LDAP_FIND_GROUP_PERMS = True
+
+    # Cache distinguished names and group memberships for an hour to minimize
+    # LDAP traffic.
+    AUTH_LDAP_CACHE_TIMEOUT = 3600
+
+    # Keep ModelBackend around for per-user permissions and maybe a local
+    # superuser.
+    AUTHENTICATION_BACKENDS = (
+        'django_auth_ldap.backend.LDAPBackend',
+        'django.contrib.auth.backends.ModelBackend',
+    )
+
+
+Contributing
+============
+
+If you'd like to contribute, the best approach is to send a well-formed pull
+request, complete with tests and documentation. Pull requests should be
+focused: trying to do more than one thing in a single request will make it more
+difficult to process.
+
+If you have a bug or feature request you can try `logging an issue`_.
+
+There's no harm in creating an issue and then submitting a pull request to
+resolve it. This can be a good way to start a conversation and can serve as an
+anchor point.
+
+.. _`logging an issue`: 
https://github.com/django-auth-ldap/django-auth-ldap/issues
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/README.rst 
new/django-auth-ldap-4.0.0/README.rst
--- old/django-auth-ldap-2.2.0/README.rst       2019-11-25 04:03:55.000000000 
+0100
+++ new/django-auth-ldap-4.0.0/README.rst       2021-05-05 15:49:26.000000000 
+0200
@@ -8,8 +8,8 @@
 .. image:: https://img.shields.io/pypi/v/django-auth-ldap.svg
    :target: https://pypi.org/project/django-auth-ldap/
 
-.. image:: 
https://img.shields.io/travis/django-auth-ldap/django-auth-ldap/master.svg?label=travis-ci
-   :target: http://travis-ci.org/django-auth-ldap/django-auth-ldap
+.. image:: 
https://github.com/django-auth-ldap/django-auth-ldap/workflows/Test/badge.svg
+   :target: 
https://github.com/django-auth-ldap/django-auth-ldap/workflows/Test/badge.svg
 
 .. image:: https://img.shields.io/pypi/l/django-auth-ldap.svg
    :target: 
https://raw.githubusercontent.com/django-auth-ldap/django-auth-ldap/master/LICENSE
@@ -22,10 +22,9 @@
 * Documentation: https://django-auth-ldap.readthedocs.io/
 * PyPI: https://pypi.org/project/django-auth-ldap/
 * Repository: https://github.com/django-auth-ldap/django-auth-ldap
-* Tests: http://travis-ci.org/django-auth-ldap/django-auth-ldap
 * License: BSD 2-Clause
 
-This version is supported on Python 3.5+; and Django 1.11+. It requires
+This version is supported on Python 3.6+; and Django 2.2+. It requires
 `python-ldap`_ >= 3.1.
 
 .. _`python-ldap`: https://pypi.org/project/python-ldap/
@@ -71,7 +70,6 @@
             'django.contrib.auth.backends.ModelBackend',
         ]
 
-.. _`python-ldap`: https://pypi.org/project/python-ldap/
 .. _`OpenLDAP`: https://www.openldap.org/
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/django_auth_ldap/__init__.py 
new/django-auth-ldap-4.0.0/django_auth_ldap/__init__.py
--- old/django-auth-ldap-2.2.0/django_auth_ldap/__init__.py     2020-06-03 
01:44:51.000000000 +0200
+++ new/django-auth-ldap-4.0.0/django_auth_ldap/__init__.py     2021-05-05 
15:49:26.000000000 +0200
@@ -1,6 +1,6 @@
-VERSION = (2, 2, 0)
-__version__ = ".".join(str(i) for i in VERSION)
-
-# Deprecated. Use VERSION and __version__ instead.
-version = VERSION
-version_string = __version__
+try:
+    from .version import version
+except ImportError:
+    __version__ = None
+else:
+    __version__ = version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/django_auth_ldap/backend.py 
new/django-auth-ldap-4.0.0/django_auth_ldap/backend.py
--- old/django-auth-ldap-2.2.0/django_auth_ldap/backend.py      2020-04-04 
16:41:40.000000000 +0200
+++ new/django-auth-ldap-4.0.0/django_auth_ldap/backend.py      2021-12-16 
13:13:26.000000000 +0100
@@ -25,12 +25,7 @@
 """
 LDAP authentication backend
 
-Complete documentation can be found in docs/howto/auth-ldap.txt (or the thing 
it
-compiles to).
-
-Use of this backend requires the python-ldap module. To support unit tests, we
-import ldap in a single centralized place (config._LDAPConfig) so that the test
-harness can insert a mock object.
+Documentation: https://django-auth-ldap.readthedocs.io/
 
 A few notes on naming conventions. If an identifier ends in _dn, it is a string
 representation of a distinguished name. If it ends in _info, it is a 2-tuple
@@ -59,7 +54,6 @@
 from django.contrib.auth.models import Group, Permission
 from django.core.cache import cache
 from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
-from django.utils.inspect import func_supports_parameter
 
 from django_auth_ldap.config import (
     ConfigurationWarning,
@@ -362,6 +356,7 @@
                 type(self.backend),
                 context="authenticate",
                 user=self._user,
+                request=self._request,
                 exception=e,
             )
             if len(results) == 0:
@@ -393,6 +388,7 @@
                         type(self.backend),
                         context="get_group_permissions",
                         user=self._user,
+                        request=self._request,
                         exception=e,
                     )
                     if len(results) == 0:
@@ -422,6 +418,7 @@
                 type(self.backend),
                 context="populate_user",
                 user=self._user,
+                request=self._request,
                 exception=e,
             )
             if len(results) == 0:
@@ -844,17 +841,7 @@
         if self._connection is None:
             uri = self.settings.SERVER_URI
             if callable(uri):
-                if func_supports_parameter(uri, "request"):
-                    uri = uri(self._request)
-                else:
-                    warnings.warn(
-                        "Update AUTH_LDAP_SERVER_URI callable %s.%s to accept "
-                        "a positional `request` argument. Support for 
callables "
-                        "accepting no arguments will be removed in a future "
-                        "version." % (uri.__module__, uri.__name__),
-                        DeprecationWarning,
-                    )
-                    uri = uri()
+                uri = uri(self._request)
 
             self._connection = self.backend.ldap.initialize(uri, 
bytes_mode=False)
 
@@ -1040,23 +1027,6 @@
             value = getattr(django.conf.settings, prefix + name, default)
             setattr(self, name, value)
 
-        # Compatibility with old caching settings.
-        if getattr(
-            django.conf.settings,
-            self._name("CACHE_GROUPS"),
-            defaults.get("CACHE_GROUPS"),
-        ):
-            warnings.warn(
-                "Found deprecated setting AUTH_LDAP_CACHE_GROUP. Use "
-                "AUTH_LDAP_CACHE_TIMEOUT instead.",
-                DeprecationWarning,
-            )
-            self.CACHE_TIMEOUT = getattr(
-                django.conf.settings,
-                self._name("GROUP_CACHE_TIMEOUT"),
-                defaults.get("GROUP_CACHE_TIMEOUT", 3600),
-            )
-
     def _name(self, suffix):
         return self._prefix + suffix
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/django_auth_ldap/version.py 
new/django-auth-ldap-4.0.0/django_auth_ldap/version.py
--- old/django-auth-ldap-2.2.0/django_auth_ldap/version.py      1970-01-01 
01:00:00.000000000 +0100
+++ new/django-auth-ldap-4.0.0/django_auth_ldap/version.py      2021-12-16 
15:17:23.000000000 +0100
@@ -0,0 +1,5 @@
+# coding: utf-8
+# file generated by setuptools_scm
+# don't change, don't track in version control
+version = '4.0.0'
+version_tuple = (4, 0, 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-auth-ldap-2.2.0/django_auth_ldap.egg-info/PKG-INFO 
new/django-auth-ldap-4.0.0/django_auth_ldap.egg-info/PKG-INFO
--- old/django-auth-ldap-2.2.0/django_auth_ldap.egg-info/PKG-INFO       
2020-06-03 01:49:56.000000000 +0200
+++ new/django-auth-ldap-4.0.0/django_auth_ldap.egg-info/PKG-INFO       
2021-12-16 15:17:23.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
 Name: django-auth-ldap
-Version: 2.2.0
+Version: 4.0.0
 Summary: Django LDAP authentication backend.
 Home-page: https://github.com/django-auth-ldap/django-auth-ldap
 Author: Peter Sagerson
@@ -9,189 +9,193 @@
 Project-URL: Documentation, https://django-auth-ldap.readthedocs.io/
 Project-URL: Source, https://github.com/django-auth-ldap/django-auth-ldap
 Project-URL: Tracker, 
https://github.com/django-auth-ldap/django-auth-ldap/issues
-Description: ================================
-        Django Authentication Using LDAP
-        ================================
-        
-        .. image:: 
https://readthedocs.org/projects/django-auth-ldap/badge/?version=latest
-           :target: https://django-auth-ldap.readthedocs.io/en/latest/
-        
-        .. image:: https://img.shields.io/pypi/v/django-auth-ldap.svg
-           :target: https://pypi.org/project/django-auth-ldap/
-        
-        .. image:: 
https://img.shields.io/travis/django-auth-ldap/django-auth-ldap/master.svg?label=travis-ci
-           :target: http://travis-ci.org/django-auth-ldap/django-auth-ldap
-        
-        .. image:: https://img.shields.io/pypi/l/django-auth-ldap.svg
-           :target: 
https://raw.githubusercontent.com/django-auth-ldap/django-auth-ldap/master/LICENSE
-        
-        This is a Django authentication backend that authenticates against an 
LDAP
-        service. Configuration can be as simple as a single distinguished name
-        template, but there are many rich configuration options for working 
with users,
-        groups, and permissions.
-        
-        * Documentation: https://django-auth-ldap.readthedocs.io/
-        * PyPI: https://pypi.org/project/django-auth-ldap/
-        * Repository: https://github.com/django-auth-ldap/django-auth-ldap
-        * Tests: http://travis-ci.org/django-auth-ldap/django-auth-ldap
-        * License: BSD 2-Clause
-        
-        This version is supported on Python 3.5+; and Django 1.11+. It requires
-        `python-ldap`_ >= 3.1.
-        
-        .. _`python-ldap`: https://pypi.org/project/python-ldap/
-        
-        
-        Installation
-        ============
-        
-        Install the package with pip:
-        
-        .. code-block:: sh
-        
-            $ pip install django-auth-ldap
-        
-        It requires `python-ldap`_ >= 3.1. You'll need the `OpenLDAP`_ 
libraries and
-        headers available on your system.
-        
-        To use the auth backend in a Django project, add
-        ``'django_auth_ldap.backend.LDAPBackend'`` to 
``AUTHENTICATION_BACKENDS``. Do
-        not add anything to ``INSTALLED_APPS``.
-        
-        .. code-block:: python
-        
-            AUTHENTICATION_BACKENDS = [
-                'django_auth_ldap.backend.LDAPBackend',
-            ]
-        
-        ``LDAPBackend`` should work with custom user models, but it does 
assume that a
-        database is present.
-        
-        .. note::
-        
-            ``LDAPBackend`` does not inherit from ``ModelBackend``. It is 
possible to
-            use ``LDAPBackend`` exclusively by configuring it to draw group 
membership
-            from the LDAP server. However, if you would like to assign 
permissions to
-            individual users or add users to groups within Django, you'll need 
to have
-            both backends installed:
-        
-            .. code-block:: python
-        
-                AUTHENTICATION_BACKENDS = [
-                    'django_auth_ldap.backend.LDAPBackend',
-                    'django.contrib.auth.backends.ModelBackend',
-                ]
-        
-        .. _`python-ldap`: https://pypi.org/project/python-ldap/
-        .. _`OpenLDAP`: https://www.openldap.org/
-        
-        
-        Example Configuration
-        =====================
-        
-        Here is a complete example configuration from ``settings.py`` that 
exercises
-        nearly all of the features. In this example, we're authenticating 
against a
-        global pool of users in the directory, but we have a special area set 
aside for
-        Django groups (``ou=django,ou=groups,dc=example,dc=com``). Remember 
that most
-        of this is optional if you just need simple authentication. Some 
default
-        settings and arguments are included for completeness.
-        
-        .. code-block:: python
-        
-            import ldap
-            from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
-        
-        
-            # Baseline configuration.
-            AUTH_LDAP_SERVER_URI = 'ldap://ldap.example.com'
-        
-            AUTH_LDAP_BIND_DN = 'cn=django-agent,dc=example,dc=com'
-            AUTH_LDAP_BIND_PASSWORD = 'phlebotinum'
-            AUTH_LDAP_USER_SEARCH = LDAPSearch(
-                'ou=users,dc=example,dc=com',
-                ldap.SCOPE_SUBTREE,
-                '(uid=%(user)s)',
-            )
-            # Or:
-            # AUTH_LDAP_USER_DN_TEMPLATE = 
'uid=%(user)s,ou=users,dc=example,dc=com'
-        
-            # Set up the basic group parameters.
-            AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
-                'ou=django,ou=groups,dc=example,dc=com',
-                ldap.SCOPE_SUBTREE,
-                '(objectClass=groupOfNames)',
-            )
-            AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr='cn')
-        
-            # Simple group restrictions
-            AUTH_LDAP_REQUIRE_GROUP = 
'cn=enabled,ou=django,ou=groups,dc=example,dc=com'
-            AUTH_LDAP_DENY_GROUP = 
'cn=disabled,ou=django,ou=groups,dc=example,dc=com'
-        
-            # Populate the Django user from the LDAP directory.
-            AUTH_LDAP_USER_ATTR_MAP = {
-                'first_name': 'givenName',
-                'last_name': 'sn',
-                'email': 'mail',
-            }
-        
-            AUTH_LDAP_USER_FLAGS_BY_GROUP = {
-                'is_active': 'cn=active,ou=django,ou=groups,dc=example,dc=com',
-                'is_staff': 'cn=staff,ou=django,ou=groups,dc=example,dc=com',
-                'is_superuser': 
'cn=superuser,ou=django,ou=groups,dc=example,dc=com',
-            }
-        
-            # This is the default, but I like to be explicit.
-            AUTH_LDAP_ALWAYS_UPDATE_USER = True
-        
-            # Use LDAP group membership to calculate group permissions.
-            AUTH_LDAP_FIND_GROUP_PERMS = True
-        
-            # Cache distinguished names and group memberships for an hour to 
minimize
-            # LDAP traffic.
-            AUTH_LDAP_CACHE_TIMEOUT = 3600
-        
-            # Keep ModelBackend around for per-user permissions and maybe a 
local
-            # superuser.
-            AUTHENTICATION_BACKENDS = (
-                'django_auth_ldap.backend.LDAPBackend',
-                'django.contrib.auth.backends.ModelBackend',
-            )
-        
-        
-        Contributing
-        ============
-        
-        If you'd like to contribute, the best approach is to send a 
well-formed pull
-        request, complete with tests and documentation. Pull requests should be
-        focused: trying to do more than one thing in a single request will 
make it more
-        difficult to process.
-        
-        If you have a bug or feature request you can try `logging an issue`_.
-        
-        There's no harm in creating an issue and then submitting a pull 
request to
-        resolve it. This can be a good way to start a conversation and can 
serve as an
-        anchor point.
-        
-        .. _`logging an issue`: 
https://github.com/django-auth-ldap/django-auth-ldap/issues
-        
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.11
 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
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: System Administrators
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3 :: Only
-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: Programming Language :: Python :: 3.10
 Classifier: Topic :: Internet :: WWW/HTTP
 Classifier: Topic :: Software Development :: Libraries :: Python Modules
 Classifier: Topic :: System :: Systems Administration :: 
Authentication/Directory :: LDAP
-Requires-Python: >=3.5
+Requires-Python: >=3.6
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+
+================================
+Django Authentication Using LDAP
+================================
+
+.. image:: 
https://readthedocs.org/projects/django-auth-ldap/badge/?version=latest
+   :target: https://django-auth-ldap.readthedocs.io/en/latest/
+
+.. image:: https://img.shields.io/pypi/v/django-auth-ldap.svg
+   :target: https://pypi.org/project/django-auth-ldap/
+
+.. image:: 
https://github.com/django-auth-ldap/django-auth-ldap/workflows/Test/badge.svg
+   :target: 
https://github.com/django-auth-ldap/django-auth-ldap/workflows/Test/badge.svg
+
+.. image:: https://img.shields.io/pypi/l/django-auth-ldap.svg
+   :target: 
https://raw.githubusercontent.com/django-auth-ldap/django-auth-ldap/master/LICENSE
+
+This is a Django authentication backend that authenticates against an LDAP
+service. Configuration can be as simple as a single distinguished name
+template, but there are many rich configuration options for working with users,
+groups, and permissions.
+
+* Documentation: https://django-auth-ldap.readthedocs.io/
+* PyPI: https://pypi.org/project/django-auth-ldap/
+* Repository: https://github.com/django-auth-ldap/django-auth-ldap
+* License: BSD 2-Clause
+
+This version is supported on Python 3.6+; and Django 2.2+. It requires
+`python-ldap`_ >= 3.1.
+
+.. _`python-ldap`: https://pypi.org/project/python-ldap/
+
+
+Installation
+============
+
+Install the package with pip:
+
+.. code-block:: sh
+
+    $ pip install django-auth-ldap
+
+It requires `python-ldap`_ >= 3.1. You'll need the `OpenLDAP`_ libraries and
+headers available on your system.
+
+To use the auth backend in a Django project, add
+``'django_auth_ldap.backend.LDAPBackend'`` to ``AUTHENTICATION_BACKENDS``. Do
+not add anything to ``INSTALLED_APPS``.
+
+.. code-block:: python
+
+    AUTHENTICATION_BACKENDS = [
+        'django_auth_ldap.backend.LDAPBackend',
+    ]
+
+``LDAPBackend`` should work with custom user models, but it does assume that a
+database is present.
+
+.. note::
+
+    ``LDAPBackend`` does not inherit from ``ModelBackend``. It is possible to
+    use ``LDAPBackend`` exclusively by configuring it to draw group membership
+    from the LDAP server. However, if you would like to assign permissions to
+    individual users or add users to groups within Django, you'll need to have
+    both backends installed:
+
+    .. code-block:: python
+
+        AUTHENTICATION_BACKENDS = [
+            'django_auth_ldap.backend.LDAPBackend',
+            'django.contrib.auth.backends.ModelBackend',
+        ]
+
+.. _`OpenLDAP`: https://www.openldap.org/
+
+
+Example Configuration
+=====================
+
+Here is a complete example configuration from ``settings.py`` that exercises
+nearly all of the features. In this example, we're authenticating against a
+global pool of users in the directory, but we have a special area set aside for
+Django groups (``ou=django,ou=groups,dc=example,dc=com``). Remember that most
+of this is optional if you just need simple authentication. Some default
+settings and arguments are included for completeness.
+
+.. code-block:: python
+
+    import ldap
+    from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
+
+
+    # Baseline configuration.
+    AUTH_LDAP_SERVER_URI = 'ldap://ldap.example.com'
+
+    AUTH_LDAP_BIND_DN = 'cn=django-agent,dc=example,dc=com'
+    AUTH_LDAP_BIND_PASSWORD = 'phlebotinum'
+    AUTH_LDAP_USER_SEARCH = LDAPSearch(
+        'ou=users,dc=example,dc=com',
+        ldap.SCOPE_SUBTREE,
+        '(uid=%(user)s)',
+    )
+    # Or:
+    # AUTH_LDAP_USER_DN_TEMPLATE = 'uid=%(user)s,ou=users,dc=example,dc=com'
+
+    # Set up the basic group parameters.
+    AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
+        'ou=django,ou=groups,dc=example,dc=com',
+        ldap.SCOPE_SUBTREE,
+        '(objectClass=groupOfNames)',
+    )
+    AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr='cn')
+
+    # Simple group restrictions
+    AUTH_LDAP_REQUIRE_GROUP = 
'cn=enabled,ou=django,ou=groups,dc=example,dc=com'
+    AUTH_LDAP_DENY_GROUP = 'cn=disabled,ou=django,ou=groups,dc=example,dc=com'
+
+    # Populate the Django user from the LDAP directory.
+    AUTH_LDAP_USER_ATTR_MAP = {
+        'first_name': 'givenName',
+        'last_name': 'sn',
+        'email': 'mail',
+    }
+
+    AUTH_LDAP_USER_FLAGS_BY_GROUP = {
+        'is_active': 'cn=active,ou=django,ou=groups,dc=example,dc=com',
+        'is_staff': 'cn=staff,ou=django,ou=groups,dc=example,dc=com',
+        'is_superuser': 'cn=superuser,ou=django,ou=groups,dc=example,dc=com',
+    }
+
+    # This is the default, but I like to be explicit.
+    AUTH_LDAP_ALWAYS_UPDATE_USER = True
+
+    # Use LDAP group membership to calculate group permissions.
+    AUTH_LDAP_FIND_GROUP_PERMS = True
+
+    # Cache distinguished names and group memberships for an hour to minimize
+    # LDAP traffic.
+    AUTH_LDAP_CACHE_TIMEOUT = 3600
+
+    # Keep ModelBackend around for per-user permissions and maybe a local
+    # superuser.
+    AUTHENTICATION_BACKENDS = (
+        'django_auth_ldap.backend.LDAPBackend',
+        'django.contrib.auth.backends.ModelBackend',
+    )
+
+
+Contributing
+============
+
+If you'd like to contribute, the best approach is to send a well-formed pull
+request, complete with tests and documentation. Pull requests should be
+focused: trying to do more than one thing in a single request will make it more
+difficult to process.
+
+If you have a bug or feature request you can try `logging an issue`_.
+
+There's no harm in creating an issue and then submitting a pull request to
+resolve it. This can be a good way to start a conversation and can serve as an
+anchor point.
+
+.. _`logging an issue`: 
https://github.com/django-auth-ldap/django-auth-ldap/issues
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-auth-ldap-2.2.0/django_auth_ldap.egg-info/SOURCES.txt 
new/django-auth-ldap-4.0.0/django_auth_ldap.egg-info/SOURCES.txt
--- old/django-auth-ldap-2.2.0/django_auth_ldap.egg-info/SOURCES.txt    
2020-06-03 01:49:56.000000000 +0200
+++ new/django-auth-ldap-4.0.0/django_auth_ldap.egg-info/SOURCES.txt    
2021-12-16 15:17:23.000000000 +0100
@@ -2,12 +2,13 @@
 LICENSE
 MANIFEST.in
 README.rst
+pyproject.toml
 setup.cfg
-setup.py
 tox.ini
 django_auth_ldap/__init__.py
 django_auth_ldap/backend.py
 django_auth_ldap/config.py
+django_auth_ldap/version.py
 django_auth_ldap.egg-info/PKG-INFO
 django_auth_ldap.egg-info/SOURCES.txt
 django_auth_ldap.egg-info/dependency_links.txt
@@ -28,6 +29,7 @@
 docs/performance.rst
 docs/permissions.rst
 docs/reference.rst
+docs/requirements.txt
 docs/users.rst
 docs/ext/daldocs.py
 tests/__init__.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-auth-ldap-2.2.0/django_auth_ldap.egg-info/requires.txt 
new/django-auth-ldap-4.0.0/django_auth_ldap.egg-info/requires.txt
--- old/django-auth-ldap-2.2.0/django_auth_ldap.egg-info/requires.txt   
2020-06-03 01:49:56.000000000 +0200
+++ new/django-auth-ldap-4.0.0/django_auth_ldap.egg-info/requires.txt   
2021-12-16 15:17:23.000000000 +0100
@@ -1,2 +1,2 @@
-Django>=1.11
+Django>=2.2
 python-ldap>=3.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/docs/conf.py 
new/django-auth-ldap-4.0.0/docs/conf.py
--- old/django-auth-ldap-2.2.0/docs/conf.py     2020-06-03 01:46:12.000000000 
+0200
+++ new/django-auth-ldap-4.0.0/docs/conf.py     2021-05-05 15:49:26.000000000 
+0200
@@ -10,9 +10,12 @@
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 
+import contextlib
 import os
 import sys
 
+from pkg_resources import DistributionNotFound, get_distribution
+
 sys.path.insert(0, os.path.abspath("ext"))
 
 
@@ -22,10 +25,29 @@
 copyright = "2009, Peter Sagerson"
 author = "Peter Sagerson"
 
-# The short X.Y version
-version = "2.2"
-# The full version, including alpha/beta/rc tags
-release = "2.2.0"
+
[email protected]
+def chdir(directory):
+    curdir = os.curdir
+    try:
+        os.chdir(directory)
+        yield
+    finally:
+        os.chdir(curdir)
+
+
+try:
+    dist = get_distribution("django-auth-ldap")
+except DistributionNotFound:
+    # The project is not installed in readthedocs environment (requires LDAP
+    # bindings). Read the version with setuptools_scm.
+    import setuptools_scm
+
+    with chdir(".."):
+        release = setuptools_scm.get_version()
+else:
+    release = dist.version
+version = ".".join(release.split(".")[:2])
 
 
 # -- General configuration ---------------------------------------------------
@@ -174,4 +196,5 @@
         "https://docs.djangoproject.com/en/stable/_objects/";,
     ),
     "pythonldap": ("https://python-ldap.readthedocs.io/en/latest/";, None),
+    "tox": ("https://tox.readthedocs.io/en/latest/";, None),
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/docs/contributing.rst 
new/django-auth-ldap-4.0.0/docs/contributing.rst
--- old/django-auth-ldap-2.2.0/docs/contributing.rst    2019-10-28 
00:55:24.000000000 +0100
+++ new/django-auth-ldap-4.0.0/docs/contributing.rst    2021-05-05 
15:49:26.000000000 +0200
@@ -18,21 +18,8 @@
 Development
 -----------
 
-To get set up for development, activate your virtualenv and use pip to install
-from ``dev-requirements.txt``:
-
-.. code-block:: sh
-
-    $ pip install -r dev-requirements.txt
-
-To run the tests:
-
-.. code-block:: sh
-
-    $ django-admin test --settings tests.settings
-
-To run the full test suite in a range of environments, run `tox`_ from the root
-of the project:
+To run the full test suite in a range of environments, run :doc:`tox 
<tox:index>`
+from the root of the project:
 
 .. code-block:: sh
 
@@ -41,4 +28,8 @@
 This includes some static analysis to detect potential runtime errors and style
 issues.
 
-.. _`tox`: https://tox.readthedocs.io/
+To limit to a single environment, use :option:`tox.-e`:
+
+.. code-block:: console
+
+   $ tox -e djangomain
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/docs/index.rst 
new/django-auth-ldap-4.0.0/docs/index.rst
--- old/django-auth-ldap-2.2.0/docs/index.rst   2019-10-28 00:55:24.000000000 
+0100
+++ new/django-auth-ldap-4.0.0/docs/index.rst   2021-05-05 15:49:26.000000000 
+0200
@@ -10,10 +10,9 @@
 * Documentation: https://django-auth-ldap.readthedocs.io/
 * PyPI: https://pypi.org/project/django-auth-ldap/
 * Repository: https://github.com/django-auth-ldap/django-auth-ldap
-* Tests: http://travis-ci.org/django-auth-ldap/django-auth-ldap
 * License: BSD 2-Clause
 
-This version is supported on Python 3.5+; and Django 1.11+. It requires
+This version is supported on Python 3.6+; and Django 2.2+. It requires
 `python-ldap`_ >= 3.1.
 
 .. toctree::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/docs/install.rst 
new/django-auth-ldap-4.0.0/docs/install.rst
--- old/django-auth-ldap-2.2.0/docs/install.rst 2019-10-28 00:55:24.000000000 
+0100
+++ new/django-auth-ldap-4.0.0/docs/install.rst 2021-10-20 11:01:15.000000000 
+0200
@@ -38,6 +38,10 @@
             "django.contrib.auth.backends.ModelBackend",
         ]
 
+    Django will check each authentication backend in order, so you are free to
+    reorder these if checking
+    :class:`~django.contrib.auth.backends.ModelBackend` first is more
+    applicable to your application.
 
 .. _`python-ldap`: https://pypi.org/project/python-ldap/
 .. _`OpenLDAP`: https://www.openldap.org/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/docs/reference.rst 
new/django-auth-ldap-4.0.0/docs/reference.rst
--- old/django-auth-ldap-2.2.0/docs/reference.rst       2020-04-04 
16:41:40.000000000 +0200
+++ new/django-auth-ldap-4.0.0/docs/reference.rst       2021-09-16 
16:26:42.000000000 +0200
@@ -83,14 +83,6 @@
 and distinguished name are cached. The value ``0``, the default, disables
 caching entirely.
 
-.. versionchanged:: 1.6.0
-
-    Previously caching was controlled by the settings `AUTH_LDAP_CACHE_GROUPS`
-    and `AUTH_LDAP_GROUP_CACHE_TIMEOUT`. If `AUTH_LDAP_CACHE_GROUPS` is set,
-    the `AUTH_LDAP_CACHE_TIMEOUT` value is derievd from these deprecated
-    settings.
-
-
 .. setting:: AUTH_LDAP_CONNECTION_OPTIONS
 
 AUTH_LDAP_CONNECTION_OPTIONS
@@ -121,11 +113,17 @@
 
 Default: ``False``
 
-If ``True``, :class:`~django_auth_ldap.backend.LDAPBackend` will furnish group
-permissions based on the LDAP groups the authenticated user belongs to.
-:setting:`AUTH_LDAP_GROUP_SEARCH` and :setting:`AUTH_LDAP_GROUP_TYPE` must 
also be
-set.
-
+If ``True``, :class:`~django_auth_ldap.backend.LDAPBackend` looks up Django
+:class:`~django.contrib.auth.models.Group`\ s matching LDAP group names, and
+assigns user permissions based on the Django
+:class:`~django.contrib.auth.models.Group` permissions.
+
+:setting:`AUTH_LDAP_GROUP_SEARCH` and :setting:`AUTH_LDAP_GROUP_TYPE` must also
+be set.
+
+.. important:: Users will not be added to the Django
+   :class:`~django.contrib.auth.models.Group`. The LDAP groups remain the
+   source of truth for group membership.
 
 .. setting:: AUTH_LDAP_GLOBAL_OPTIONS
 
@@ -174,8 +172,9 @@
 
 Default: ``None``
 
-If ``True``, :class:`~django_auth_ldap.backend.LDAPBackend` will mirror a 
user's
-LDAP group membership in the Django database. Any time a user authenticates, we
+If ``True``, :class:`~django_auth_ldap.backend.LDAPBackend` will mirror a
+user's LDAP group membership in the Django database. Any time a user
+authenticates through the :class:`~django_auth_ldap.backend.LDAPBackend`, we
 will create all of their LDAP groups as Django groups and update their Django
 group membership to exactly match their LDAP group membership. If the LDAP
 server has nested groups, the Django database will end up with a flattened
@@ -185,6 +184,10 @@
 only mirror those groups and leave the rest alone. This is ignored if
 :setting:`AUTH_LDAP_MIRROR_GROUPS_EXCEPT` is set.
 
+.. note:: Users authenticating through another authentication backend, such as
+   :class:`~django.contrib.auth.backends.ModelBackend` will **not** have their
+   group membership and permissions refreshed from the LDAP server.
+
 
 .. setting:: AUTH_LDAP_MIRROR_GROUPS_EXCEPT
 
@@ -560,12 +563,14 @@
 
 
     This is a Django signal that is sent when we receive an
-    :exc:`ldap.LDAPError` exception. The signal has three keyword arguments:
+    :exc:`ldap.LDAPError` exception. The signal has four keyword arguments:
 
     - ``context``: one of ``'authenticate'``, ``'get_group_permissions'``, or
       ``'populate_user'``, indicating which API was being called when the
       exception was caught.
     - ``user``: the Django user being processed (if available).
+    - ``request``: the Django request object associated with the
+      authentication attempt (if available).
     - ``exception``: the :exc:`~ldap.LDAPError` object itself.
 
     The sender is the :class:`~django_auth_ldap.backend.LDAPBackend` class (or
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/docs/requirements.txt 
new/django-auth-ldap-4.0.0/docs/requirements.txt
--- old/django-auth-ldap-2.2.0/docs/requirements.txt    1970-01-01 
01:00:00.000000000 +0100
+++ new/django-auth-ldap-4.0.0/docs/requirements.txt    2021-05-05 
15:49:26.000000000 +0200
@@ -0,0 +1 @@
+setuptools_scm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/pyproject.toml 
new/django-auth-ldap-4.0.0/pyproject.toml
--- old/django-auth-ldap-2.2.0/pyproject.toml   1970-01-01 01:00:00.000000000 
+0100
+++ new/django-auth-ldap-4.0.0/pyproject.toml   2021-11-30 18:50:56.000000000 
+0100
@@ -0,0 +1,10 @@
+[build-system]
+requires = [
+    "setuptools>=42",
+    "wheel",
+    "setuptools_scm[toml]>=3.4",
+]
+build-backend = "setuptools.build_meta:__legacy__"
+
+[tool.setuptools_scm]
+write_to = "django_auth_ldap/version.py"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/setup.cfg 
new/django-auth-ldap-4.0.0/setup.cfg
--- old/django-auth-ldap-2.2.0/setup.cfg        2020-06-03 01:49:56.902470600 
+0200
+++ new/django-auth-ldap-4.0.0/setup.cfg        2021-12-16 15:17:23.934657000 
+0100
@@ -1,8 +1,8 @@
 [metadata]
 name = django-auth-ldap
-version = attr: django_auth_ldap.__version__
 description = Django LDAP authentication backend.
 long_description = file: README.rst
+long_description_content_type = text/x-rst
 author = Peter Sagerson
 author_email = [email protected]
 url = https://github.com/django-auth-ldap/django-auth-ldap
@@ -11,19 +11,21 @@
        Development Status :: 5 - Production/Stable
        Environment :: Web Environment
        Framework :: Django
-       Framework :: Django :: 1.11
        Framework :: Django :: 2.2
-       Framework :: Django :: 3.0
+       Framework :: Django :: 3.1
+       Framework :: Django :: 3.2
+       Framework :: Django :: 4.0
        Intended Audience :: Developers
        Intended Audience :: System Administrators
        License :: OSI Approved :: BSD License
        Programming Language :: Python
        Programming Language :: Python :: 3
        Programming Language :: Python :: 3 :: Only
-       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
+       Programming Language :: Python :: 3.10
        Topic :: Internet :: WWW/HTTP
        Topic :: Software Development :: Libraries :: Python Modules
        Topic :: System :: Systems Administration :: Authentication/Directory 
:: LDAP
@@ -33,24 +35,17 @@
        Tracker = https://github.com/django-auth-ldap/django-auth-ldap/issues
 
 [options]
-python_requires = >=3.5
+python_requires = >=3.6
 packages = django_auth_ldap
 install_requires = 
-       Django>=1.11
+       Django>=2.2
        python-ldap>=3.1
 
 [flake8]
-ignore = 
-       E501
-       W503
+max-line-length = 88
 
 [isort]
-combine_as_imports = True
-default_section = THIRDPARTY
-include_trailing_comma = True
-known_first_party = django_auth_ldap
-line_length = 88
-multi_line_output = 3
+profile = black
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/setup.py 
new/django-auth-ldap-4.0.0/setup.py
--- old/django-auth-ldap-2.2.0/setup.py 2019-11-25 04:03:55.000000000 +0100
+++ new/django-auth-ldap-4.0.0/setup.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-from setuptools import setup
-
-setup()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/tests/settings.py 
new/django-auth-ldap-4.0.0/tests/settings.py
--- old/django-auth-ldap-2.2.0/tests/settings.py        2019-10-28 
00:55:24.000000000 +0100
+++ new/django-auth-ldap-4.0.0/tests/settings.py        2021-05-05 
15:49:26.000000000 +0200
@@ -3,5 +3,6 @@
 INSTALLED_APPS = ("django.contrib.auth", "django.contrib.contenttypes", 
"tests")
 
 DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3"}}
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
 
 AUTHENTICATION_BACKENDS = ["django_auth_ldap.backend.LDAPBackend"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/tests/tests.py 
new/django-auth-ldap-4.0.0/tests/tests.py
--- old/django-auth-ldap-2.2.0/tests/tests.py   2019-12-04 05:06:11.000000000 
+0100
+++ new/django-auth-ldap-4.0.0/tests/tests.py   2021-12-16 13:08:39.000000000 
+0100
@@ -27,11 +27,10 @@
 import logging
 import os
 import pickle
-import warnings
 from copy import deepcopy
+from unittest import mock
 
 import ldap
-import mock
 import slapdtest
 from django.contrib.auth import authenticate, get_backends
 from django.contrib.auth.models import Group, Permission, User
@@ -133,15 +132,15 @@
         cls.server = slapdtest.SlapdObject()
         cls.server.suffix = "o=test"
         cls.server.openldap_schema_files = [
-            "core.schema",
-            "cosine.schema",
-            "inetorgperson.schema",
-            "nis.schema",
+            "core.ldif",
+            "cosine.ldif",
+            "inetorgperson.ldif",
+            "nis.ldif",
         ]
         cls.server.start()
         with open(os.path.join(here, "tests.ldif")) as fp:
             ldif = fp.read()
-        cls.server.ldapadd(ldif)
+        cls.server.slapadd(ldif)
 
     @classmethod
     def tearDownClass(cls):
@@ -178,29 +177,6 @@
         self.assertEqual(User.objects.count(), user_count + 1)
         cb_mock.assert_called_with(request)
 
-    def test_deprecated_callable_server_uri(self):
-        self._init_settings(
-            SERVER_URI=lambda: self.server.ldap_uri,
-            USER_DN_TEMPLATE="uid=%(user)s,ou=people,o=test",
-        )
-        user_count = User.objects.count()
-
-        with warnings.catch_warnings(record=True) as w:
-            warnings.simplefilter("always")
-            user = authenticate(username="alice", password="password")
-
-        self.assertIs(user.has_usable_password(), False)
-        self.assertEqual(user.username, "alice")
-        self.assertEqual(User.objects.count(), user_count + 1)
-        self.assertEqual(len(w), 1)
-        self.assertEqual(w[0].category, DeprecationWarning)
-        self.assertEqual(
-            str(w[0].message),
-            "Update AUTH_LDAP_SERVER_URI callable tests.tests.<lambda> to "
-            "accept a positional `request` argument. Support for callables "
-            "accepting no arguments will be removed in a future version.",
-        )
-
     def test_simple_bind(self):
         self._init_settings(USER_DN_TEMPLATE="uid=%(user)s,ou=people,o=test")
         user_count = User.objects.count()
@@ -265,7 +241,7 @@
 
     @spy_ldap("simple_bind_s")
     def test_simple_bind_escaped(self, mock):
-        """ Bind with a username that requires escaping. """
+        """Bind with a username that requires escaping."""
         self._init_settings(USER_DN_TEMPLATE="uid=%(user)s,ou=people,o=test")
 
         user = authenticate(username="alice,1", password="password")
@@ -418,7 +394,7 @@
 
     @spy_ldap("search_s")
     def test_search_bind_escaped(self, mock):
-        """ Search for a username that requires escaping. """
+        """Search for a username that requires escaping."""
         self._init_settings(
             USER_SEARCH=LDAPSearch(
                 "ou=people,o=test", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"
@@ -644,11 +620,13 @@
 
         with catch_signal(ldap_error) as handler:
             handler.side_effect = handle_ldap_error
+            request = RequestFactory().get("/")
             with self.assertRaises(ldap.LDAPError):
-                authenticate(username="alice", password="password")
+                authenticate(request=request, username="alice", 
password="password")
         handler.assert_called_once()
         _args, kwargs = handler.call_args
         self.assertEqual(kwargs["context"], "authenticate")
+        self.assertEqual(kwargs["request"], request)
 
     def test_populate_signal_ldap_error(self):
         self._init_settings(
@@ -1562,29 +1540,6 @@
         # DN is cached.
         self.assertEqual(
             cache.get("django_auth_ldap.user_dn.alice"), 
"uid=alice,ou=people,o=test"
-        )
-
-    def test_deprecated_cache_groups(self):
-        self._init_settings(
-            USER_SEARCH=LDAPSearch(
-                "ou=people,o=test", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"
-            ),
-            CACHE_GROUPS=True,
-        )
-        with warnings.catch_warnings(record=True) as w:
-            warnings.simplefilter("always")
-            user = authenticate(username="alice", password="password")
-        self.assertIsNotNone(user)
-        self.assertEqual(len(w), 1)
-        self.assertEqual(w[0].category, DeprecationWarning)
-        self.assertEqual(
-            str(w[0].message),
-            "Found deprecated setting AUTH_LDAP_CACHE_GROUP. Use "
-            "AUTH_LDAP_CACHE_TIMEOUT instead.",
-        )
-        # DN is cached.
-        self.assertEqual(
-            cache.get("django_auth_ldap.user_dn.alice"), 
"uid=alice,ou=people,o=test"
         )
 
     #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-auth-ldap-2.2.0/tox.ini 
new/django-auth-ldap-4.0.0/tox.ini
--- old/django-auth-ldap-2.2.0/tox.ini  2019-12-04 05:06:11.000000000 +0100
+++ new/django-auth-ldap-4.0.0/tox.ini  2021-12-16 13:13:26.000000000 +0100
@@ -4,45 +4,52 @@
     flake8
     isort
     docs
-    py{35,36,37}-django111
-    py{35,36,37,38}-django22
-    py{36,37,38}-django30
-    py{36,37,38}-djangomaster
+    django22
+    django31
+    django32
+    djangomain
+isolated_build = true
 
 [testenv]
 commands = {envpython} -Wa -b -m django test --settings tests.settings
 deps =
-    django111: Django~=1.11.0
     django22: Django~=2.2.0
-    django30: Django>=3.0<3.1
-    djangomaster: https://github.com/django/django/archive/master.tar.gz
-    mock >= 2.0.0
+    django31: Django>=3.1,<3.2
+    django32: Django>=3.2,<4.0
+    django40: Django>=4.0,<4.1
+    djangomain: https://github.com/django/django/archive/main.tar.gz
 
 [testenv:black]
-basepython = python3
 deps = black
 commands = black --check --diff .
 skip_install = true
 
 [testenv:flake8]
-basepython = python3
 deps = flake8
 commands = flake8
 skip_install = true
 
 [testenv:isort]
-basepython = python3
-deps = isort
-commands = isort --check-only --diff
+deps = isort>=5.0.1
+commands = isort --check --diff .
 skip_install = true
 
 [testenv:docs]
-basepython = python3
+isolated_build = true
 deps =
     readme_renderer
     sphinx
 commands =
     make -C docs html
-    {envpython} setup.py check --restructuredtext --strict
-skip_install = true
 whitelist_externals = make
+
+[testenv:packaging]
+deps =
+    build
+    setuptools
+    twine
+    wheel
+skip_install = true
+commands =
+    python -m build
+    twine check dist/*

Reply via email to