Hello community,

here is the log from the commit of package python-django-extensions for 
openSUSE:Leap:15.2 checked in at 2020-04-14 14:21:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/python-django-extensions (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.python-django-extensions.new.3248 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-extensions"

Tue Apr 14 14:21:10 2020 rev:3 rq:793527 version:2.2.9

Changes:
--------
--- 
/work/SRC/openSUSE:Leap:15.2/python-django-extensions/python-django-extensions.changes
      2020-02-25 12:18:48.596634746 +0100
+++ 
/work/SRC/openSUSE:Leap:15.2/.python-django-extensions.new.3248/python-django-extensions.changes
    2020-04-14 14:21:32.177299350 +0200
@@ -1,0 +2,9 @@
+Fri Apr  3 10:45:05 UTC 2020 - Tomáš Chvátal <[email protected]>
+
+- Update to 2.2.9:
+  * Fix: shell_plus, move notebook down the list of prefered shells
+  * Fix: sqldiff, fix KeyError when detecting missing (unique) indexes
+  * Improvement: encrypted fields, make it harder to use deprecated keyczar 
fields
+  * Locale: Removed empty localizations
+
+-------------------------------------------------------------------

Old:
----
  django-extensions-2.2.8.tar.gz

New:
----
  django-extensions-2.2.9.tar.gz

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

Other differences:
------------------
++++++ python-django-extensions.spec ++++++
--- /var/tmp/diff_new_pack.FKRE5h/_old  2020-04-14 14:21:32.513299601 +0200
+++ /var/tmp/diff_new_pack.FKRE5h/_new  2020-04-14 14:21:32.517299605 +0200
@@ -18,7 +18,7 @@
 
 %define skip_python2 1
 Name:           python-django-extensions
-Version:        2.2.8
+Version:        2.2.9
 Release:        0
 Summary:        Extensions for Django
 License:        BSD-3-Clause

++++++ django-extensions-2.2.8.tar.gz -> django-extensions-2.2.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.8/.github/FUNDING.yml 
new/django-extensions-2.2.9/.github/FUNDING.yml
--- old/django-extensions-2.2.8/.github/FUNDING.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/django-extensions-2.2.9/.github/FUNDING.yml     2020-03-26 
23:44:45.000000000 +0100
@@ -0,0 +1,6 @@
+# These are supported funding model platforms
+
+github: [trbs]
+patreon: djangoextensions
+open_collective: djangoextensions
+custom: 
['https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=P57EJJ9QYL232']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.8/CHANGELOG.md 
new/django-extensions-2.2.9/CHANGELOG.md
--- old/django-extensions-2.2.8/CHANGELOG.md    2020-02-10 20:05:14.000000000 
+0100
+++ new/django-extensions-2.2.9/CHANGELOG.md    2020-03-26 23:44:45.000000000 
+0100
@@ -1,6 +1,16 @@
 Changelog
 =========
 
+2.2.9
+-----
+
+Changes:
+ - Fix: shell_plus, move notebook down the list of prefered shells
+ - Fix: sqldiff, fix KeyError when detecting missing (unique) indexes
+ - Improvement: encrypted fields, make it harder to use deprecated keyczar 
fields
+ - Locale: Removed empty localizations
+
+
 2.2.8
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/__init__.py 
new/django-extensions-2.2.9/django_extensions/__init__.py
--- old/django-extensions-2.2.8/django_extensions/__init__.py   2020-02-10 
20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/django_extensions/__init__.py   2020-03-26 
23:44:45.000000000 +0100
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-VERSION = (2, 2, 8)
+VERSION = (2, 2, 9)
 
 
 def get_version(version):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/db/fields/encrypted.py 
new/django-extensions-2.2.9/django_extensions/db/fields/encrypted.py
--- old/django-extensions-2.2.8/django_extensions/db/fields/encrypted.py        
2020-02-10 20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/django_extensions/db/fields/encrypted.py        
2020-03-26 23:44:45.000000000 +0100
@@ -34,6 +34,15 @@
             stacklevel=2,
         )
 
+        if not getattr(settings, 'ENCRYPTED_KEYCZAR_THISISUNSAFE', None):
+            raise ImproperlyConfigured(
+                "Please do not use these fields. Since Keyczar is deprecated 
and authors deleted "
+                "all code we highly recommend to stop using potentially unsafe 
abandonware directly "
+                "these versions of encrypted fields will be removed soon but 
it's highly likely their "
+                "names will be reused. Please see github issues/1359 for 
discussion on possible "
+                "replacement fields",
+            )
+
         if not getattr(settings, 'ENCRYPTED_FIELD_KEYS_DIR', None):
             raise ImproperlyConfigured('You must set the 
settings.ENCRYPTED_FIELD_KEYS_DIR '
                                        'setting to your Keyczar keys 
directory.')
Binary files 
old/django-extensions-2.2.8/django_extensions/locale/cs/LC_MESSAGES/django.mo 
and 
new/django-extensions-2.2.9/django_extensions/locale/cs/LC_MESSAGES/django.mo 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/locale/cs/LC_MESSAGES/django.po 
new/django-extensions-2.2.9/django_extensions/locale/cs/LC_MESSAGES/django.po
--- 
old/django-extensions-2.2.8/django_extensions/locale/cs/LC_MESSAGES/django.po   
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/locale/cs/LC_MESSAGES/django.po   
    1970-01-01 01:00:00.000000000 +0100
@@ -1,77 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: django-extensions\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-02 11:42+0100\n"
-"PO-Revision-Date: 2011-02-02 10:42+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <[email protected]>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: cs\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
-
-#: admin/__init__.py:121
-msgid "and"
-msgstr ""
-
-#: admin/__init__.py:123
-#, python-format
-msgid ""
-"Use the left field to do %(model_name)s lookups in the fields %(field_list)s."
-msgstr ""
-
-#: db/models.py:15
-msgid "created"
-msgstr ""
-
-#: db/models.py:16
-msgid "modified"
-msgstr ""
-
-#: db/models.py:26
-msgid "title"
-msgstr ""
-
-#: db/models.py:27
-msgid "slug"
-msgstr ""
-
-#: db/models.py:28
-msgid "description"
-msgstr ""
-
-#: db/models.py:50
-msgid "Inactive"
-msgstr ""
-
-#: db/models.py:51
-msgid "Active"
-msgstr ""
-
-#: db/models.py:53
-msgid "status"
-msgstr ""
-
-#: db/models.py:56
-msgid "keep empty for an immediate activation"
-msgstr ""
-
-#: db/models.py:58
-msgid "keep empty for indefinite activation"
-msgstr ""
-
-#: management/commands/show_urls.py:34
-#, python-format
-msgid "%s does not appear to be a urlpattern object"
-msgstr ""
-
-#: templates/django_extensions/widgets/foreignkey_searchinput.html:4
-msgid "Lookup"
-msgstr ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/locale/el/LC_MESSAGES/django.po 
new/django-extensions-2.2.9/django_extensions/locale/el/LC_MESSAGES/django.po
--- 
old/django-extensions-2.2.8/django_extensions/locale/el/LC_MESSAGES/django.po   
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/locale/el/LC_MESSAGES/django.po   
    2020-03-26 23:44:45.000000000 +0100
@@ -72,7 +72,7 @@
 #: management/commands/show_urls.py:34
 #, python-format
 msgid "%s does not appear to be a urlpattern object"
-msgstr "% s δεν φαίνεται να είναι ένα αντικείμενο urlpattern"
+msgstr "%s δεν φαίνεται να είναι ένα αντικείμενο urlpattern"
 
 #: templates/django_extensions/widgets/foreignkey_searchinput.html:4
 msgid "Lookup"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/locale/en/LC_MESSAGES/django.po 
new/django-extensions-2.2.9/django_extensions/locale/en/LC_MESSAGES/django.po
--- 
old/django-extensions-2.2.8/django_extensions/locale/en/LC_MESSAGES/django.po   
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/locale/en/LC_MESSAGES/django.po   
    2020-03-26 23:44:45.000000000 +0100
@@ -8,69 +8,105 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-02 11:42+0100\n"
+"POT-Creation-Date: 2020-02-10 20:37+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <[email protected]>\n"
+"Language: en\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: admin/__init__.py:121
+#: admin/__init__.py:142
 msgid "and"
 msgstr ""
 
-#: admin/__init__.py:123
+#: admin/__init__.py:144
 #, python-format
 msgid ""
 "Use the left field to do %(model_name)s lookups in the fields %(field_list)s."
 msgstr ""
 
-#: db/models.py:15
+#: admin/filter.py:24 admin/filter.py:53
+msgid "Yes"
+msgstr ""
+
+#: admin/filter.py:25 admin/filter.py:54
+msgid "No"
+msgstr ""
+
+#: admin/filter.py:32
+msgid "All"
+msgstr ""
+
+#: db/models.py:18
 msgid "created"
 msgstr ""
 
-#: db/models.py:16
+#: db/models.py:19
 msgid "modified"
 msgstr ""
 
-#: db/models.py:26
+#: db/models.py:38
 msgid "title"
 msgstr ""
 
-#: db/models.py:27
-msgid "slug"
+#: db/models.py:39
+msgid "description"
 msgstr ""
 
-#: db/models.py:28
-msgid "description"
+#: db/models.py:60
+msgid "slug"
 msgstr ""
 
-#: db/models.py:50
+#: db/models.py:121 mongodb/models.py:76
 msgid "Inactive"
 msgstr ""
 
-#: db/models.py:51
+#: db/models.py:122 mongodb/models.py:77
 msgid "Active"
 msgstr ""
 
-#: db/models.py:53
+#: db/models.py:124
 msgid "status"
 msgstr ""
 
-#: db/models.py:56
+#: db/models.py:125 mongodb/models.py:80
 msgid "keep empty for an immediate activation"
 msgstr ""
 
-#: db/models.py:58
+#: db/models.py:126 mongodb/models.py:81
 msgid "keep empty for indefinite activation"
 msgstr ""
 
-#: management/commands/show_urls.py:34
+#: mongodb/fields/__init__.py:22
 #, python-format
-msgid "%s does not appear to be a urlpattern object"
+msgid "String (up to %(max_length)s)"
+msgstr ""
+
+#: validators.py:14
+msgid "Control Characters like new lines or tabs are not allowed."
 msgstr ""
 
-#: templates/django_extensions/widgets/foreignkey_searchinput.html:4
-msgid "Lookup"
+#: validators.py:48
+msgid "Leading and Trailing whitespaces are not allowed."
+msgstr ""
+
+#: validators.py:74
+msgid "Only a hex string is allowed."
+msgstr ""
+
+#: validators.py:75
+#, python-format
+msgid "Invalid length. Must be %(length)d characters."
+msgstr ""
+
+#: validators.py:76
+#, python-format
+msgid "Ensure that there are more than %(min)s characters."
+msgstr ""
+
+#: validators.py:77
+#, python-format
+msgid "Ensure that there are no more than %(max)s characters."
 msgstr ""
Binary files 
old/django-extensions-2.2.8/django_extensions/locale/et/LC_MESSAGES/django.mo 
and 
new/django-extensions-2.2.9/django_extensions/locale/et/LC_MESSAGES/django.mo 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/locale/et/LC_MESSAGES/django.po 
new/django-extensions-2.2.9/django_extensions/locale/et/LC_MESSAGES/django.po
--- 
old/django-extensions-2.2.8/django_extensions/locale/et/LC_MESSAGES/django.po   
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/locale/et/LC_MESSAGES/django.po   
    1970-01-01 01:00:00.000000000 +0100
@@ -1,75 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-02 11:43+0100\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <[email protected]>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: admin/__init__.py:121
-msgid "and"
-msgstr "ja"
-
-#: admin/__init__.py:123
-#, python-format
-msgid ""
-"Use the left field to do %(model_name)s lookups in the fields %(field_list)s."
-msgstr ""
-
-#: db/models.py:15
-msgid "created"
-msgstr ""
-
-#: db/models.py:16
-msgid "modified"
-msgstr ""
-
-#: db/models.py:26
-msgid "title"
-msgstr ""
-
-#: db/models.py:27
-msgid "slug"
-msgstr ""
-
-#: db/models.py:28
-msgid "description"
-msgstr ""
-
-#: db/models.py:50
-msgid "Inactive"
-msgstr ""
-
-#: db/models.py:51
-msgid "Active"
-msgstr ""
-
-#: db/models.py:53
-msgid "status"
-msgstr ""
-
-#: db/models.py:56
-msgid "keep empty for an immediate activation"
-msgstr ""
-
-#: db/models.py:58
-msgid "keep empty for indefinite activation"
-msgstr ""
-
-#: management/commands/show_urls.py:34
-#, python-format
-msgid "%s does not appear to be a urlpattern object"
-msgstr ""
-
-#: templates/django_extensions/widgets/foreignkey_searchinput.html:4
-msgid "Lookup"
-msgstr ""
Binary files 
old/django-extensions-2.2.8/django_extensions/locale/sk/LC_MESSAGES/django.mo 
and 
new/django-extensions-2.2.9/django_extensions/locale/sk/LC_MESSAGES/django.mo 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/locale/sk/LC_MESSAGES/django.po 
new/django-extensions-2.2.9/django_extensions/locale/sk/LC_MESSAGES/django.po
--- 
old/django-extensions-2.2.8/django_extensions/locale/sk/LC_MESSAGES/django.po   
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/locale/sk/LC_MESSAGES/django.po   
    1970-01-01 01:00:00.000000000 +0100
@@ -1,77 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: django-extensions\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-02 11:43+0100\n"
-"PO-Revision-Date: 2011-02-02 10:42+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <[email protected]>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: sk\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n"
-
-#: admin/__init__.py:121
-msgid "and"
-msgstr ""
-
-#: admin/__init__.py:123
-#, python-format
-msgid ""
-"Use the left field to do %(model_name)s lookups in the fields %(field_list)s."
-msgstr ""
-
-#: db/models.py:15
-msgid "created"
-msgstr ""
-
-#: db/models.py:16
-msgid "modified"
-msgstr ""
-
-#: db/models.py:26
-msgid "title"
-msgstr ""
-
-#: db/models.py:27
-msgid "slug"
-msgstr ""
-
-#: db/models.py:28
-msgid "description"
-msgstr ""
-
-#: db/models.py:50
-msgid "Inactive"
-msgstr ""
-
-#: db/models.py:51
-msgid "Active"
-msgstr ""
-
-#: db/models.py:53
-msgid "status"
-msgstr ""
-
-#: db/models.py:56
-msgid "keep empty for an immediate activation"
-msgstr ""
-
-#: db/models.py:58
-msgid "keep empty for indefinite activation"
-msgstr ""
-
-#: management/commands/show_urls.py:34
-#, python-format
-msgid "%s does not appear to be a urlpattern object"
-msgstr ""
-
-#: templates/django_extensions/widgets/foreignkey_searchinput.html:4
-msgid "Lookup"
-msgstr ""
Binary files 
old/django-extensions-2.2.8/django_extensions/locale/tr/LC_MESSAGES/django.mo 
and 
new/django-extensions-2.2.9/django_extensions/locale/tr/LC_MESSAGES/django.mo 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/locale/tr/LC_MESSAGES/django.po 
new/django-extensions-2.2.9/django_extensions/locale/tr/LC_MESSAGES/django.po
--- 
old/django-extensions-2.2.8/django_extensions/locale/tr/LC_MESSAGES/django.po   
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/locale/tr/LC_MESSAGES/django.po   
    1970-01-01 01:00:00.000000000 +0100
@@ -1,77 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: django-extensions\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-02 11:43+0100\n"
-"PO-Revision-Date: 2011-02-02 10:42+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <[email protected]>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: tr\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-
-#: admin/__init__.py:121
-msgid "and"
-msgstr ""
-
-#: admin/__init__.py:123
-#, python-format
-msgid ""
-"Use the left field to do %(model_name)s lookups in the fields %(field_list)s."
-msgstr ""
-
-#: db/models.py:15
-msgid "created"
-msgstr ""
-
-#: db/models.py:16
-msgid "modified"
-msgstr ""
-
-#: db/models.py:26
-msgid "title"
-msgstr ""
-
-#: db/models.py:27
-msgid "slug"
-msgstr ""
-
-#: db/models.py:28
-msgid "description"
-msgstr ""
-
-#: db/models.py:50
-msgid "Inactive"
-msgstr ""
-
-#: db/models.py:51
-msgid "Active"
-msgstr ""
-
-#: db/models.py:53
-msgid "status"
-msgstr ""
-
-#: db/models.py:56
-msgid "keep empty for an immediate activation"
-msgstr ""
-
-#: db/models.py:58
-msgid "keep empty for indefinite activation"
-msgstr ""
-
-#: management/commands/show_urls.py:34
-#, python-format
-msgid "%s does not appear to be a urlpattern object"
-msgstr ""
-
-#: templates/django_extensions/widgets/foreignkey_searchinput.html:4
-msgid "Lookup"
-msgstr ""
Binary files 
old/django-extensions-2.2.8/django_extensions/locale/zh_CN/LC_MESSAGES/django.mo
 and 
new/django-extensions-2.2.9/django_extensions/locale/zh_CN/LC_MESSAGES/django.mo
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/locale/zh_CN/LC_MESSAGES/django.po
 
new/django-extensions-2.2.9/django_extensions/locale/zh_CN/LC_MESSAGES/django.po
--- 
old/django-extensions-2.2.8/django_extensions/locale/zh_CN/LC_MESSAGES/django.po
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/locale/zh_CN/LC_MESSAGES/django.po
    1970-01-01 01:00:00.000000000 +0100
@@ -1,77 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: django-extensions\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-02-02 11:43+0100\n"
-"PO-Revision-Date: 2011-02-02 10:42+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <[email protected]>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_CN\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-
-#: admin/__init__.py:121
-msgid "and"
-msgstr ""
-
-#: admin/__init__.py:123
-#, python-format
-msgid ""
-"Use the left field to do %(model_name)s lookups in the fields %(field_list)s."
-msgstr ""
-
-#: db/models.py:15
-msgid "created"
-msgstr ""
-
-#: db/models.py:16
-msgid "modified"
-msgstr ""
-
-#: db/models.py:26
-msgid "title"
-msgstr ""
-
-#: db/models.py:27
-msgid "slug"
-msgstr ""
-
-#: db/models.py:28
-msgid "description"
-msgstr ""
-
-#: db/models.py:50
-msgid "Inactive"
-msgstr ""
-
-#: db/models.py:51
-msgid "Active"
-msgstr ""
-
-#: db/models.py:53
-msgid "status"
-msgstr ""
-
-#: db/models.py:56
-msgid "keep empty for an immediate activation"
-msgstr ""
-
-#: db/models.py:58
-msgid "keep empty for indefinite activation"
-msgstr ""
-
-#: management/commands/show_urls.py:34
-#, python-format
-msgid "%s does not appear to be a urlpattern object"
-msgstr ""
-
-#: templates/django_extensions/widgets/foreignkey_searchinput.html:4
-msgid "Lookup"
-msgstr ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/management/commands/shell_plus.py 
new/django-extensions-2.2.9/django_extensions/management/commands/shell_plus.py
--- 
old/django-extensions-2.2.8/django_extensions/management/commands/shell_plus.py 
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/management/commands/shell_plus.py 
    2020-03-26 23:44:45.000000000 +0100
@@ -450,12 +450,12 @@
 
         with monkey_patch_cursordebugwrapper(print_sql=options["print_sql"] or 
print_sql, print_sql_location=options["print_sql_location"], 
confprefix="SHELL_PLUS"):
             shells = (
-                ('notebook', self.get_notebook),
                 ('ptipython', self.get_ptipython),
                 ('ptpython', self.get_ptpython),
                 ('bpython', self.get_bpython),
                 ('ipython', self.get_ipython),
                 ('plain', self.get_plain),
+                ('notebook', self.get_notebook),
                 ('idle', self.get_idle),
             )
             SETTINGS_SHELL_PLUS = getattr(settings, 'SHELL_PLUS', None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/management/commands/sqldiff.py 
new/django-extensions-2.2.9/django_extensions/management/commands/sqldiff.py
--- 
old/django-extensions-2.2.8/django_extensions/management/commands/sqldiff.py    
    2020-02-10 20:05:14.000000000 +0100
+++ 
new/django-extensions-2.2.9/django_extensions/management/commands/sqldiff.py    
    2020-03-26 23:44:45.000000000 +0100
@@ -439,8 +439,10 @@
 
             columns = constraint['columns']
             if len(columns) == 1:
-                field = fields[columns[0]]
-                if field.unique:
+                field = fields.get(columns[0])
+                if field is None:
+                    pass
+                elif field.unique:
                     continue
             else:
                 if tuple(columns) in unique_together:
@@ -487,11 +489,11 @@
                 continue
 
             columns = constraint['columns']
-            if constraint['unique'] and constraint['index']:
+            field = fields.get(columns[0])
+            if (constraint['unique'] and constraint['index']) or field is None:
                 # unique indexes do not exist in django ? only unique 
constraints
                 pass
             elif len(columns) == 1:
-                field = fields[columns[0]]
                 if constraint['primary_key'] and field.primary_key:
                     continue
                 if constraint['foreign_key'] and isinstance(field, 
models.ForeignKey) and field.db_constraint:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/django_extensions/management/utils.py 
new/django-extensions-2.2.9/django_extensions/management/utils.py
--- old/django-extensions-2.2.8/django_extensions/management/utils.py   
2020-02-10 20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/django_extensions/management/utils.py   
2020-03-26 23:44:45.000000000 +0100
@@ -8,7 +8,7 @@
 
 def _make_writeable(filename):
     """
-    Make sure that the file is writeable. Useful if our source is
+    Make sure that the file is writable. Useful if our source is
     read-only.
     """
     import stat
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.8/docs/command_extensions.rst 
new/django-extensions-2.2.9/docs/command_extensions.rst
--- old/django-extensions-2.2.8/docs/command_extensions.rst     2020-02-10 
20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/docs/command_extensions.rst     2020-03-26 
23:44:45.000000000 +0100
@@ -121,7 +121,7 @@
 
 * *update_permissions* - Reloads permissions for specified apps, or all apps 
if no args are specified.
 
-* *validate_templates* - Validate templates on syntax and compile errors.
+* :doc:`validate_templates` - Validate templates on syntax and compile errors.
 
 * *set_default_site* - Set parameters of the default `django.contrib.sites` 
Site using `name` and `domain` or `system-fqdn`.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.8/docs/conf.py 
new/django-extensions-2.2.9/docs/conf.py
--- old/django-extensions-2.2.8/docs/conf.py    2020-02-10 20:05:14.000000000 
+0100
+++ new/django-extensions-2.2.9/docs/conf.py    2020-03-26 23:44:45.000000000 
+0100
@@ -47,7 +47,7 @@
 # The short X.Y version.
 version = '2.2'
 # The full version, including alpha/beta/rc tags.
-release = '2.2.8'
+release = '2.2.9'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.8/docs/index.rst 
new/django-extensions-2.2.9/docs/index.rst
--- old/django-extensions-2.2.8/docs/index.rst  2020-02-10 20:05:14.000000000 
+0100
+++ new/django-extensions-2.2.9/docs/index.rst  2020-03-26 23:44:45.000000000 
+0100
@@ -43,8 +43,6 @@
 
 This might mean the django-extensions may work with older or unsupported 
versions but we do not guarantee it and most likely will not fix bugs related 
to incompatibilities with older versions.
 
-At this time we test on and thrive to support valid combinations of Python 
2.7, 3.5, 3.6, 3.7, pypy and pypy3 with Django versions 1.11 to 2.1.
-
 Contents
 ========
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.8/docs/validate_templates.rst 
new/django-extensions-2.2.9/docs/validate_templates.rst
--- old/django-extensions-2.2.8/docs/validate_templates.rst     2020-02-10 
20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/docs/validate_templates.rst     2020-03-26 
23:44:45.000000000 +0100
@@ -3,6 +3,18 @@
 
 :synopsis: Checks templates on syntax or compile errors.
 
+This will catch any invalid Django template syntax, for example::
+
+    {% foobar %}
+
+    {% comment %}
+    This throws this error:
+    TemplateSyntaxError Invalid block tag on line 1: 'foobar'. Did you forget 
to register or load this tag?
+    {% endcomment %}
+
+Note that this will not catch invalid HTML, only errors in the Django template
+syntax used.
+
 Options
 -------
 
@@ -56,4 +68,17 @@
 Usage Example
 -------------
 
- ./manage.py validate_templates
+::
+
+    ./manage.py validate_templates
+
+
+You can also integrate it with your tests, like this::
+
+    import unittest
+    from django.core.management import call_command
+
+    class MyTests(unittest.TestCase):
+        def test_validate_templates(self):
+            call_command("validate_templates")
+            # This throws an error if it fails to validate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/tests/db/fields/test_encrypted.py 
new/django-extensions-2.2.9/tests/db/fields/test_encrypted.py
--- old/django-extensions-2.2.8/tests/db/fields/test_encrypted.py       
2020-02-10 20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/tests/db/fields/test_encrypted.py       
1970-01-01 01:00:00.000000000 +0100
@@ -1,140 +0,0 @@
-# -*- coding: utf-8 -*-
-import os
-import six
-import shutil
-from tempfile import mkdtemp
-
-import django
-import pytest
-from django.core.exceptions import ImproperlyConfigured
-from django.forms.widgets import Textarea, TextInput
-from django.test import TestCase
-from django.test.utils import override_settings
-
-try:
-    from django_extensions.db.fields.encrypted import BaseEncryptedField, 
EncryptedCharField, EncryptedTextField
-    keyczar_active = True
-except ImportError:
-    keyczar_active = False
-
-try:
-    from unittest.mock import patch
-except ImportError:
-    from mock import patch
-
-
-KEYCZAR_META = '''{"name": "Test", "purpose": "DECRYPT_AND_ENCRYPT", "type": 
"RSA_PRIV", "encrypted": false, "versions": [{"versionNumber": 1, "status": 
"PRIMARY", "exportable": false}]}'''  # noqa
-KEYCZAR_1 = '''{"publicKey": {"modulus": 
"AKljEv64fu7jXoyURILoKcYueSXCodwXuvSgjGAV9I9SWUGAKc_0pj2s5xr8eiuhUrcscdSIFD58JwfdWHikI5YhhkxURBa_1DQ3nkMKWVugzuFk5i_8bVOp0Vp-GOAhHEFfyqxhM1yMJrvarCB23scErLVdM99v7ULrL0_Gcwk2jfoFw8pV7shlJ16WL4mM1yFBrE8Eru-iKkhXoo0XiNgk9PMrmys4q_vnWbcw19V0ywY-ks9Q7d0HzNOYmaWLoTUf4RRR72eeVIcrSAgERLsYW6ukk5sr6QGNWLSgft_nahKQazWlqTP4yRV8iTv-GxAn6IJeeiDzFGJV7myxxXs",
 "publicExponent": "AQAB", "size": 2048}, "privateExponent": 
"a7VFGdWlWTAZKhkJq5gHIC7i-CDYHYS1a-I_AMZVOWFqwhzF-aceom80kVNkOCQf3bwUMcnJ3aXCh9y26hetTUTKCfU3SqP2QrHvH8AP7BTIGEi5ml_QAPgl2H4AQVysg-FulchFCZ9Q7fjxpL8Rj8moLLc0Ser5GqlD711IPt150IdhfRiK35_ksskBsH-a-695kg-DO8Gf5T1KX0b79y5HumbViwtJJzrxPvGx9_FyhkqKyaIA9h33J1YBHz4VCD20oEGzBC4WnK-gqLselY3Qcdz3_449vI9-3Y7r69VXFopREm6Noz6s53-Cg0kMs62mCiRJYeJGFtiaqaaEsQ",
 "primeP": 
"ANfWqgciiwTLyYAEaoYI6E7R82HoWPooEf1GhqKyqhVtd47Ap-FOKi-APAYF7b4NcbV6SJPl6BqjsiDqsdJ3PnjDY_eUbEEkDjmGuYPKT8pRi8XHEOzxm4ARzMIgysTWXtzteyFFeKmhc3cqM6xORqLei1ZwU5mFM4xCrrbcD6fz",
 "primeQ": 
"AMjnuGL1JVvKy5rBOOjoe7ia02vtNzUOsdLSUr5NoFODxsIi64UFhzVmA6xvlK_zZeFWoe784_JpXJGKuJ3Bs_kJR2jgVc71Q0Nc8fn0LIFvkrQ6tMZ5XTfLEIHCH8psHA2Q_vR7yRAACZXfY5we2HB9979p6sOsapqgNgWTyJZZ",
 "primeExponentP": 
"awt8whMgrV1AbyxBhH4wcL7xnRI15sMuwNVUeqZvcjcbP4JPAI_anjpUCoywLzzNszqVejxg061x759WV9Jp-ky1bJmA4wG1yFQH99PDpMyyrIEg5NKi026AhZrr1ZmX7KwfEA47XK3E7UnR3Nfpcmc65cDJxW7pdNuxeOFFJn8",
 "primeExponentQ": 
"XrDgtjuHHSmLJ2iU0ynoTk0jAwZuc-J2K8CX4TwjKdm9T3k3-p1tadyoNJjuwrN8vGWhs0ucgH_qcmqosyo-Ek2uS58Yso_k4RYosr_ETklxIuNcmwNOzWI3aIE_jJ_B5R8HG-JQFOt_mRUOFOJw7yxgHeblEM7t--0xKRXLgBk",
 "crtCoefficient": 
"AMr3lac4iHbnKSO4fwyY2WPaIhKM8VWZC3DEkA9Y4uYt8Xe4diw6K_n0e0t_u46fgBcTzj0vNUCiC_i1kcAuLKH2oZUOvAUhoYnjss9LHu9TRI28QEHj6OW0Gghjr4IyW5jg7SYbQngJmnA4QgbMibqFvtKdBSTf-5okujE8QVSb",
 "size": 2048}'''  # noqa
-ENCRYPTED_TEST_VALUE = 
'enc_str:::AGFc2bEtqb4ybkQ7kGBBJEnsEPMJAjX5BIIWNKok-g8r2D2WNNt3CbUen2oYr_a5cCN0kvCTfRgBiuaJO04ioB3OuGI-KrQbeJp9GZbs8zc0jTsd7MIgJz6saqmWbZwNDPZYxNBnqdRDxCo1B-nnNrUzYJRb7d0nn_iPwUY4avOLiePCqDX_NRZ7WVooZjzTkRpfpiPvC3gWuKzoz0Cu2AuwdEcO9422BtRDhI30yu7dk5VUL6Zv3OxOz5fvFkJjW-eg3EcGfj2q7_J-YWLVkWsrrwdFJK4w4Yeqkl06qF5sdkakJn2rJJRsSTcDj0ceWAqfnEECdtHkXe0LpfZY1zH_Hwyz'
  # noqa
-
-
-class BaseEncryptedFieldTestCase(TestCase):
-
-    @classmethod
-    def setUpClass(cls):  # noqa
-        cls.tmpdir = mkdtemp()
-        with open(os.path.join(cls.tmpdir, 'meta'), 'w') as f:
-            f.write(KEYCZAR_META)
-        with open(os.path.join(cls.tmpdir, '1'), 'w') as f:
-            f.write(KEYCZAR_1)
-
-    @classmethod
-    def tearDownClass(cls):  # noqa
-        shutil.rmtree(cls.tmpdir)
-
-
[email protected](keyczar_active is False, reason="Encrypted fields needs 
that keyczar is installed")
-class BaseEncryptionFieldExceptions(TestCase):
-    """Tests for BaseEncryptedField exceptions."""
-
-    @override_settings(
-        ENCRYPTED_FIELD_KEYS_DIR=None,
-        ENCRYPTED_FIELD_MODE='INVALID'
-    )
-    def 
test_should_raise_ImproperlyConfigured_if_ENCRYPTED_FIELD_KEYS_DIR_is_not_set(self):
  # noqa
-        with six.assertRaisesRegex(
-                self,
-            ImproperlyConfigured,
-            'You must set the settings.ENCRYPTED_FIELD_KEYS_DIR setting to 
your Keyczar keys directory'):  # noqa
-            BaseEncryptedField()
-
-    @override_settings(
-        ENCRYPTED_FIELD_KEYS_DIR='/srv/keys',
-        ENCRYPTED_FIELD_MODE='INVALID'
-    )
-    def 
test_should_raise_ImproperlyConfigured_if_invalid_ENCRYPTED_FIELD_MODE_is_set(self):
  # noqa
-        with six.assertRaisesRegex(
-                self,
-                ImproperlyConfigured,
-                'ENCRYPTED_FIELD_MODE must be either DECRYPT_AND_ENCRYPT or 
ENCRYPT, not INVALID.'):  # noqa
-            BaseEncryptedField()
-
-
[email protected](keyczar_active is False, reason="Encrypted fields needs 
that keyczar is installed")
-class EncryptedCharFieldTests(BaseEncryptedFieldTestCase):
-
-    def test_should_return_formfield_with_TextInput_widget(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            formfield = EncryptedCharField(max_length=50).formfield()
-
-        self.assertTrue(isinstance(formfield.widget, TextInput))
-        self.assertEqual(formfield.max_length, 358)
-
-    @override_settings(ENCRYPTED_FIELD_MODE='ENCRYPT')
-    @patch('django_extensions.db.fields.encrypted.keyczar')
-    def test_should_encrypt_foo_and_return_encrypted_value_with_prefix(self, 
m_keyczar):  # noqa
-        m_keyczar.Encrypter.Read.return_value.Encrypt.return_value = 
'encrypted_foo'  # noqa
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            field = EncryptedCharField(max_length=50)
-
-        result = field.get_db_prep_save('foo', None)
-
-        self.assertTrue(result.startswith('enc_str:::encrypted_foo'))
-
-    @pytest.mark.skipif(django.VERSION < (2, 0), reason='run only on Django 
greater than 2.0')
-    def test_should_decrypt_encrypted_str(self):  # noqa
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            field = EncryptedCharField(max_length=50)
-
-        result = field.from_db_value(ENCRYPTED_TEST_VALUE, None, None)
-
-        self.assertEqual(result, 'test')
-
-    @override_settings(ENCRYPTED_FIELD_MODE='ENCRYPT')
-    def test_should_return_encrypted_str_if_Decrypt_is_not_available(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            field = EncryptedCharField(max_length=50)
-
-        result = field.to_python(ENCRYPTED_TEST_VALUE)
-
-        self.assertEqual(result, ENCRYPTED_TEST_VALUE)
-
-    def test_should_return_encrypted_str_if_value_not_start_with_prefix(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            field = EncryptedCharField(max_length=50)
-
-        result = field.to_python('encrypted_value_without_prefix')
-
-        self.assertEqual(result, 'encrypted_value_without_prefix')
-
-    def test_should_return_CharField_as_internal_type(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            internal_type = 
EncryptedCharField(max_length=50).get_internal_type()
-
-        self.assertEqual(internal_type, 'CharField')
-
-
[email protected](keyczar_active is False, reason="Encrypted fields needs 
that keyczar is installed")
-class EncryptedTextFieldTests(BaseEncryptedFieldTestCase):
-
-    def test_should_return_formfield_with_Textarea_widget(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            formfield = EncryptedTextField(max_length=50).formfield()
-
-        self.assertTrue(isinstance(formfield.widget, Textarea))
-
-    def test_should_return_TextField_as_internal_type(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            internal_type = 
EncryptedTextField(max_length=50).get_internal_type()
-
-        self.assertEqual(internal_type, 'TextField')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/tests/management/commands/test_graph_models.py 
new/django-extensions-2.2.9/tests/management/commands/test_graph_models.py
--- old/django-extensions-2.2.8/tests/management/commands/test_graph_models.py  
2020-02-10 20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/tests/management/commands/test_graph_models.py  
2020-03-26 23:44:45.000000000 +0100
@@ -28,7 +28,7 @@
 
 @contextmanager
 def temp_output_file(extension=""):
-    """Create writeable tempfile in filesystem and ensure it gets deleted"""
+    """Create writable tempfile in filesystem and ensure it gets deleted"""
     tmpfile = tempfile.NamedTemporaryFile(suffix=extension, delete=False)
     tmpfile.close()
     yield tmpfile.name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-extensions-2.2.8/tests/test_encrypted_fields.py 
new/django-extensions-2.2.9/tests/test_encrypted_fields.py
--- old/django-extensions-2.2.8/tests/test_encrypted_fields.py  2020-02-10 
20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/tests/test_encrypted_fields.py  1970-01-01 
01:00:00.000000000 +0100
@@ -1,291 +0,0 @@
-# -*- coding: utf-8 -*-
-import six
-import shutil
-import tempfile
-from contextlib import contextmanager
-
-import pytest
-from django.conf import settings
-from django.core.exceptions import ImproperlyConfigured
-from django.db import connection, models
-from django.forms.widgets import Textarea, TextInput
-from django.test import TestCase
-from django.test.utils import override_settings
-
-from .testapp.models import Secret
-
-# Only perform encrypted fields tests if keyczar is present. Resolves
-# http://github.com/django-extensions/django-extensions/issues/#issue/17
-try:
-    from django_extensions.db.fields.encrypted import BaseEncryptedField, 
EncryptedCharField, EncryptedTextField
-    from keyczar import keyczar, keyczart, keyinfo  # NOQA
-    keyczar_active = True
-except ImportError:
-    keyczar_active = False
-
-# Locations of both private and public keys.
-KEY_LOCS = {}
-
-
[email protected](scope="class")
-def keyczar_keys(request):
-    # If KeyCzar is available, set up the environment.
-    if keyczar_active:
-        # Create an RSA private key.
-        keys_dir = tempfile.mkdtemp("django_extensions_tests_keyzcar_rsa_dir")
-        keyczart.Create(keys_dir, "test", keyinfo.DECRYPT_AND_ENCRYPT, 
asymmetric=True)
-        keyczart.AddKey(keys_dir, "PRIMARY", size=4096)
-        KEY_LOCS['DECRYPT_AND_ENCRYPT'] = keys_dir
-
-        # Create an RSA public key.
-        pub_dir = tempfile.mkdtemp("django_extensions_tests_keyzcar_pub_dir")
-        keyczart.PubKey(keys_dir, pub_dir)
-        KEY_LOCS['ENCRYPT'] = pub_dir
-
-    # cleanup crypto key temp dirs
-    def cleanup():
-        for name, path in KEY_LOCS.items():
-            shutil.rmtree(path)
-    request.addfinalizer(cleanup)
-
-
-@contextmanager
-def keys(purpose, mode=None):
-    """
-    A context manager that sets up the correct KeyCzar environment for a test.
-
-    Arguments:
-        purpose: Either keyczar.keyinfo.DECRYPT_AND_ENCRYPT or
-                 keyczar.keyinfo.ENCRYPT.
-        mode: If truthy, settings.ENCRYPTED_FIELD_MODE will be set to (and then
-              reverted from) this value. If falsy, 
settings.ENCRYPTED_FIELD_MODE
-              will not be changed. Optional. Default: None.
-
-    Yields:
-        A Keyczar subclass for the stated purpose. This will be keyczar.Crypter
-        for DECRYPT_AND_ENCRYPT or keyczar.Encrypter for ENCRYPT. In addition,
-        settings.ENCRYPTED_FIELD_KEYS_DIR will be set correctly, and then
-        reverted when the manager exits.
-    """
-    # Store the original settings so we can restore when the manager exits.
-    orig_setting_dir = getattr(settings, 'ENCRYPTED_FIELD_KEYS_DIR', None)
-    orig_setting_mode = getattr(settings, 'ENCRYPTED_FIELD_MODE', None)
-    try:
-        if mode:
-            settings.ENCRYPTED_FIELD_MODE = mode
-
-        if purpose == keyinfo.DECRYPT_AND_ENCRYPT:
-            settings.ENCRYPTED_FIELD_KEYS_DIR = KEY_LOCS['DECRYPT_AND_ENCRYPT']
-            yield keyczar.Crypter.Read(settings.ENCRYPTED_FIELD_KEYS_DIR)
-        else:
-            settings.ENCRYPTED_FIELD_KEYS_DIR = KEY_LOCS['ENCRYPT']
-            yield keyczar.Encrypter.Read(settings.ENCRYPTED_FIELD_KEYS_DIR)
-    except Exception:
-        raise  # Reraise any exceptions.
-    finally:
-        # Restore settings.
-        settings.ENCRYPTED_FIELD_KEYS_DIR = orig_setting_dir
-        if mode:
-            if orig_setting_mode:
-                settings.ENCRYPTED_FIELD_MODE = orig_setting_mode
-            else:
-                del settings.ENCRYPTED_FIELD_MODE
-
-
-@contextmanager
-def secret_model():
-    """
-    A context manager that yields a Secret model defined at runtime.
-
-    All EncryptedField init logic occurs at model class definition time, not at
-    object instantiation time. This means that in order to test different keys
-    and modes, we must generate a new class definition at runtime, after
-    establishing the correct KeyCzar settings. This context manager handles
-    that process.
-
-    See https://dynamic-models.readthedocs.io/en/latest/ and
-    https://docs.djangoproject.com/en/dev/topics/db/models/
-        #differences-between-proxy-inheritance-and-unmanaged-models
-    """
-
-    # Create a new class that shadows tests.models.Secret.
-    attrs = {
-        'name': EncryptedCharField("Name", 
max_length=Secret._meta.get_field('name').max_length),
-        'text': EncryptedTextField("Text"),
-        '__module__': 'tests.testapp.models',
-        'Meta': type('Meta', (object, ), {
-            'managed': False,
-            'db_table': Secret._meta.db_table
-        })
-    }
-    yield type('Secret', (models.Model, ), attrs)
-
-
[email protected](keyczar_active is False, reason="Encrypted fields needs 
that keyczar is installed")
[email protected]("admin_user", "keyczar_keys")
-class EncryptedFieldsTestCase(TestCase):
-    def test_char_field_create(self):
-        """
-        Uses a private key to encrypt data on model creation.
-        Verifies the data is encrypted in the database and can be decrypted.
-        """
-        with keys(keyinfo.DECRYPT_AND_ENCRYPT) as crypt:
-            with secret_model() as model:
-                test_val = "Test Secret"
-                secret = model.objects.create(name=test_val)
-
-                cursor = connection.cursor()
-                query = "SELECT name FROM %s WHERE id = %d" % 
(model._meta.db_table, secret.id)
-                cursor.execute(query)
-                db_val, = cursor.fetchone()
-                decrypted_val = 
crypt.Decrypt(db_val[len(EncryptedCharField.prefix):])
-                self.assertEqual(test_val, decrypted_val)
-
-    def test_char_field_read(self):
-        """
-        Uses a private key to encrypt data on model creation.
-        Verifies the data is decrypted when reading the value back from the
-        model.
-        """
-        with keys(keyinfo.DECRYPT_AND_ENCRYPT):
-            with secret_model() as model:
-                test_val = "Test Secret"
-                secret = model.objects.create(name=test_val)
-                retrieved_secret = model.objects.get(id=secret.id)
-                self.assertEqual(test_val, retrieved_secret.name)
-
-    def test_text_field_create(self):
-        """
-        Uses a private key to encrypt data on model creation.
-        Verifies the data is encrypted in the database and can be decrypted.
-        """
-        with keys(keyinfo.DECRYPT_AND_ENCRYPT) as crypt:
-            with secret_model() as model:
-                test_val = "Test Secret"
-                secret = model.objects.create(text=test_val)
-                cursor = connection.cursor()
-                query = "SELECT text FROM %s WHERE id = %d" % 
(model._meta.db_table, secret.id)
-                cursor.execute(query)
-                db_val, = cursor.fetchone()
-                decrypted_val = 
crypt.Decrypt(db_val[len(EncryptedCharField.prefix):])
-                self.assertEqual(test_val, decrypted_val)
-
-    def test_text_field_read(self):
-        """
-        Uses a private key to encrypt data on model creation.
-        Verifies the data is decrypted when reading the value back from the
-        model.
-        """
-        with keys(keyinfo.DECRYPT_AND_ENCRYPT):
-            with secret_model() as model:
-                test_val = "Test Secret"
-                secret = model.objects.create(text=test_val)
-                retrieved_secret = model.objects.get(id=secret.id)
-                self.assertEqual(test_val, retrieved_secret.text)
-
-    def test_cannot_decrypt(self):
-        """
-        Uses a public key to encrypt data on model creation.
-        Verifies that the data cannot be decrypted using the same key.
-        """
-        with keys(keyinfo.ENCRYPT, mode=keyinfo.ENCRYPT.name):
-            with secret_model() as model:
-                test_val = "Test Secret"
-                secret = model.objects.create(name=test_val)
-                retrieved_secret = model.objects.get(id=secret.id)
-                self.assertNotEqual(test_val, retrieved_secret.name)
-                
self.assertTrue(retrieved_secret.name.startswith(EncryptedCharField.prefix))
-
-    def test_unacceptable_purpose(self):
-        """
-        Tries to create an encrypted field with a mode mismatch.
-        A purpose of "DECRYPT_AND_ENCRYPT" cannot be used with a public key,
-        since public keys cannot be used for decryption. This should raise an
-        exception.
-        """
-        with self.assertRaises(keyczar.errors.KeyczarError):
-            with keys(keyinfo.ENCRYPT):
-                with secret_model():
-                    # A KeyCzar exception should get raised during class
-                    # definition time, so any code in here would never get run.
-                    pass
-
-    def test_decryption_forbidden(self):
-        """
-        Uses a private key to encrypt data, but decryption is not allowed.
-        ENCRYPTED_FIELD_MODE is explicitly set to ENCRYPT, meaning data should
-        not be decrypted, even though the key would allow for it.
-        """
-        with keys(keyinfo.DECRYPT_AND_ENCRYPT, mode=keyinfo.ENCRYPT.name):
-            with secret_model() as model:
-                test_val = "Test Secret"
-                secret = model.objects.create(name=test_val)
-                retrieved_secret = model.objects.get(id=secret.id)
-                self.assertNotEqual(test_val, retrieved_secret.name)
-                
self.assertTrue(retrieved_secret.name.startswith(EncryptedCharField.prefix))
-
-    def test_encrypt_public_decrypt_private(self):
-        """
-        Uses a public key to encrypt, and a private key to decrypt data.
-        """
-        test_val = "Test Secret"
-
-        # First, encrypt data with public key and save to db.
-        with keys(keyinfo.ENCRYPT, mode=keyinfo.ENCRYPT.name):
-            with secret_model() as model:
-                secret = model.objects.create(name=test_val)
-                enc_retrieved_secret = model.objects.get(id=secret.id)
-                self.assertNotEqual(test_val, enc_retrieved_secret.name)
-                
self.assertTrue(enc_retrieved_secret.name.startswith(EncryptedCharField.prefix))
-
-        # Next, retrieve data from db, and decrypt with private key.
-        with keys(keyinfo.DECRYPT_AND_ENCRYPT):
-            with secret_model() as model:
-                retrieved_secret = model.objects.get(id=secret.id)
-                self.assertEqual(test_val, retrieved_secret.name)
-
-
-class BaseEncryptedFieldTestCase(TestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        cls.tmpdir = tempfile.mkdtemp()
-        keyczart.Create(cls.tmpdir, "test", keyinfo.DECRYPT_AND_ENCRYPT, 
asymmetric=True)
-        keyczart.AddKey(cls.tmpdir, "PRIMARY", size=4096)
-
-    @classmethod
-    def tearDownClass(cls):
-        shutil.rmtree(cls.tmpdir)
-
-
[email protected](keyczar_active is False, reason="Encrypted fields needs 
that keyczar is installed")
-class BaseEncryptedFieldExceptions(BaseEncryptedFieldTestCase):
-    """Tests for BaseEncryptedField exceptions."""
-
-    def 
test_should_raise_ImproperlyConfigured_if_invalid_ENCRYPTED_FIELD_MODE_is_set(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir, 
ENCRYPTED_FIELD_MODE='INVALID'):
-            with six.assertRaisesRegex(self, ImproperlyConfigured, 
'ENCRYPTED_FIELD_MODE must be either DECRYPT_AND_ENCRYPT or ENCRYPT, not 
INVALID.'):
-                BaseEncryptedField()
-
-
[email protected](keyczar_active is False, reason="Encrypted fields needs 
that keyczar is installed")
-class EncryptedTextFieldTests(BaseEncryptedFieldTestCase):
-    """Tests for EncryptedTextField."""
-
-    def test_should_return_formfield_with_Textarea_widget(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            formfield = EncryptedTextField(max_length=50).formfield()
-
-        self.assertTrue(isinstance(formfield.widget, Textarea))
-
-
[email protected](keyczar_active is False, reason="Encrypted fields needs 
that keyczar is installed")
-class EncryptedCharFieldTests(BaseEncryptedFieldTestCase):
-    """Tests for EncryptedCharField."""
-
-    def test_should_return_formfield_with_TextInput_widget(self):
-        with override_settings(ENCRYPTED_FIELD_KEYS_DIR=self.tmpdir):
-            formfield = EncryptedCharField(max_length=50).formfield()
-
-        self.assertTrue(isinstance(formfield.widget, TextInput))
-        self.assertEqual(formfield.max_length, 700)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-extensions-2.2.8/tests/testapp/settings.py 
new/django-extensions-2.2.9/tests/testapp/settings.py
--- old/django-extensions-2.2.8/tests/testapp/settings.py       2020-02-10 
20:05:14.000000000 +0100
+++ new/django-extensions-2.2.9/tests/testapp/settings.py       2020-03-26 
23:44:45.000000000 +0100
@@ -71,7 +71,6 @@
     'django_extensions.db.fields.encrypted',
     'django_extensions.mongodb.fields',
     'django_extensions.mongodb.models',
-    'tests.test_encrypted_fields',
     'tests.testapp.scripts.invalid_import_script',
     'setup',
 ]


Reply via email to