Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-django-taggit for 
openSUSE:Factory checked in at 2023-01-04 17:53:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-taggit (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-taggit.new.1563 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-taggit"

Wed Jan  4 17:53:41 2023 rev:2 rq:1055862 version:3.1.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-taggit/python-django-taggit.changes    
    2022-10-15 16:40:55.138652516 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-django-taggit.new.1563/python-django-taggit.changes
      2023-01-04 17:53:58.990669802 +0100
@@ -1,0 +2,14 @@
+Wed Jan  4 14:23:43 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 3.1.0:
+  * Add Python 3.11 support
+  * Add Django 4.1 support
+  * Fixed an issue where object caches would not be properly cleared after
+    updating tags, leading
+  to stale reads in cases where ``prefetch_related`` is used.
+  * Change ``TagListSerializerField`` to be a subclass of ``ListField``.
+    This should improve support for API document generation. This change
+    should not affect API behavior, but might affect metaprogramming code,
+    so please procede carefully during this update.
+
+-------------------------------------------------------------------

Old:
----
  django-taggit-3.0.0.tar.gz

New:
----
  django-taggit-3.1.0.tar.gz

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

Other differences:
------------------
++++++ python-django-taggit.spec ++++++
--- /var/tmp/diff_new_pack.uVNHib/_old  2023-01-04 17:53:59.462672584 +0100
+++ /var/tmp/diff_new_pack.uVNHib/_new  2023-01-04 17:53:59.466672608 +0100
@@ -1,7 +1,7 @@
 #
-# spec file for package python-django-taggit
+# spec file
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -23,7 +23,7 @@
 BuildArch:      noarch
 %endif
 Name:           python-%{mod_name}
-Version:        3.0.0
+Version:        3.1.0
 Release:        0
 Summary:        Django-taggit is a reusable Django application for simple 
tagging
 License:        BSD-3-Clause-Clear

++++++ django-taggit-3.0.0.tar.gz -> django-taggit-3.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/CHANGELOG.rst 
new/django-taggit-3.1.0/CHANGELOG.rst
--- old/django-taggit-3.0.0/CHANGELOG.rst       2022-05-02 09:39:57.000000000 
+0200
+++ new/django-taggit-3.1.0/CHANGELOG.rst       2022-11-18 05:56:41.000000000 
+0100
@@ -4,6 +4,15 @@
 (Unreleased)
 ~~~~~~~~~~~~
 
+3.1.0 (2022-11-08)
+~~~~~~~~~~~~~~~~~~
+
+* Add Python 3.11 support (no code changes were needed, but now we test this 
release).
+* Add Django 4.1 support (no code changes were needed, but now we test this 
release).
+* Fixed an issue where object caches would not be properly cleared after 
updating tags, leading
+  to stale reads in cases where ``prefetch_related`` is used.
+* Change ``TagListSerializerField`` to be a subclass of ``ListField``. This 
should improve support for API document generation. This change should not 
affect API behavior, but might affect metaprogramming code, so please procede 
carefully during this update.
+
 3.0.0 (2022-05-02)
 ~~~~~~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/PKG-INFO 
new/django-taggit-3.1.0/PKG-INFO
--- old/django-taggit-3.0.0/PKG-INFO    2022-05-02 09:40:09.205214000 +0200
+++ new/django-taggit-3.1.0/PKG-INFO    2022-11-18 05:56:53.237284200 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: django-taggit
-Version: 3.0.0
+Version: 3.1.0
 Summary: django-taggit is a reusable Django application for simple tagging.
 Home-page: https://github.com/jazzband/django-taggit
 Author: Alex Gaynor
@@ -9,12 +9,12 @@
 Project-URL: Documentation, https://django-taggit.readthedocs.io
 Project-URL: Source, https://github.com/jazzband/django-taggit
 Project-URL: Tracker, https://github.com/jazzband/django-taggit/issues
-Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
 Classifier: Framework :: Django :: 3.2
 Classifier: Framework :: Django :: 4.0
+Classifier: Framework :: Django :: 4.1
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
@@ -26,6 +26,7 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Requires-Python: >=3.6
 License-File: LICENSE
 License-File: AUTHORS
@@ -95,5 +96,3 @@
 <https://django-taggit.readthedocs.io/>`_. And for questions about usage or
 development you can create an issue on Github (if your question is about
 usage please add the `question` tag).
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/django_taggit.egg-info/PKG-INFO 
new/django-taggit-3.1.0/django_taggit.egg-info/PKG-INFO
--- old/django-taggit-3.0.0/django_taggit.egg-info/PKG-INFO     2022-05-02 
09:40:08.000000000 +0200
+++ new/django-taggit-3.1.0/django_taggit.egg-info/PKG-INFO     2022-11-18 
05:56:53.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: django-taggit
-Version: 3.0.0
+Version: 3.1.0
 Summary: django-taggit is a reusable Django application for simple tagging.
 Home-page: https://github.com/jazzband/django-taggit
 Author: Alex Gaynor
@@ -9,12 +9,12 @@
 Project-URL: Documentation, https://django-taggit.readthedocs.io
 Project-URL: Source, https://github.com/jazzband/django-taggit
 Project-URL: Tracker, https://github.com/jazzband/django-taggit/issues
-Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Web Environment
 Classifier: Framework :: Django
 Classifier: Framework :: Django :: 3.2
 Classifier: Framework :: Django :: 4.0
+Classifier: Framework :: Django :: 4.1
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
@@ -26,6 +26,7 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
 Requires-Python: >=3.6
 License-File: LICENSE
 License-File: AUTHORS
@@ -95,5 +96,3 @@
 <https://django-taggit.readthedocs.io/>`_. And for questions about usage or
 development you can create an issue on Github (if your question is about
 usage please add the `question` tag).
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/docs/api.rst 
new/django-taggit-3.1.0/docs/api.rst
--- old/django-taggit-3.0.0/docs/api.rst        2022-05-02 09:39:57.000000000 
+0200
+++ new/django-taggit-3.1.0/docs/api.rst        2022-11-18 05:56:41.000000000 
+0100
@@ -72,7 +72,7 @@
         just an iterable) containing the name of each tag as a string::
 
             >>> apple.tags.names()
-            [u'green and juicy', u'red']
+            ["green and juicy", "red"]
 
     .. method:: slugs()
 
@@ -80,7 +80,7 @@
         just an iterable) containing the slug of each tag as a string::
 
             >>> apple.tags.slugs()
-            [u'green-and-juicy', u'red']
+            ["green-and-juicy", "red"]
 
     .. hint::
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/docs/faq.rst 
new/django-taggit-3.1.0/docs/faq.rst
--- old/django-taggit-3.0.0/docs/faq.rst        2022-05-02 09:39:57.000000000 
+0200
+++ new/django-taggit-3.1.0/docs/faq.rst        2022-11-18 05:56:41.000000000 
+0100
@@ -3,7 +3,7 @@
 
 - How can I get all my tags?
 
- If you are using just an out-of-the-box setup, your tags are storred in the 
`Tag` model (found in `taggit.models`). If this is a custom model (for example 
you have your own models derived from `ItemBase`), then you'll need to query 
that one instead.
+ If you are using just an out-of-the-box setup, your tags are stored in the 
`Tag` model (found in `taggit.models`). If this is a custom model (for example 
you have your own models derived from `ItemBase`), then you'll need to query 
that one instead.
 
  So if you are using the standard setup, ``Tag.objects.all()`` will give you 
the tags.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/docs/getting_started.rst 
new/django-taggit-3.1.0/docs/getting_started.rst
--- old/django-taggit-3.0.0/docs/getting_started.rst    2022-05-02 
09:39:57.000000000 +0200
+++ new/django-taggit-3.1.0/docs/getting_started.rst    2022-11-18 
05:56:41.000000000 +0100
@@ -38,8 +38,8 @@
 
   When set to ``True``, tag lookups will be case insensitive. This defaults to 
``False``.
 
-`` ``TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING``
-  When this is set to ``True``, tag slugs will be limited to ASCII characters. 
In this case, if you also have ```unidecode`` installed,
+* ``TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING``
+  When this is set to ``True``, tag slugs will be limited to ASCII characters. 
In this case, if you also have ``unidecode`` installed,
   then tag sluggification will transform a tag like ``あい うえお`` to 
``ai-ueo``.
   If you do not have ``unidecode`` installed, then you will usually be 
outright stripping unicode, meaning that something like ``helloあい`` will be 
slugified as ``hello``.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/setup.cfg 
new/django-taggit-3.1.0/setup.cfg
--- old/django-taggit-3.0.0/setup.cfg   2022-05-02 09:40:09.209214000 +0200
+++ new/django-taggit-3.1.0/setup.cfg   2022-11-18 05:56:53.241284600 +0100
@@ -13,6 +13,7 @@
        Framework :: Django
        Framework :: Django :: 3.2
        Framework :: Django :: 4.0
+       Framework :: Django :: 4.1
        Intended Audience :: Developers
        License :: OSI Approved :: BSD License
        Operating System :: OS Independent
@@ -24,6 +25,7 @@
        Programming Language :: Python :: 3.8
        Programming Language :: Python :: 3.9
        Programming Language :: Python :: 3.10
+       Programming Language :: Python :: 3.11
 project_urls = 
        Documentation = https://django-taggit.readthedocs.io
        Source = https://github.com/jazzband/django-taggit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/taggit/__init__.py 
new/django-taggit-3.1.0/taggit/__init__.py
--- old/django-taggit-3.0.0/taggit/__init__.py  2022-05-02 09:39:57.000000000 
+0200
+++ new/django-taggit-3.1.0/taggit/__init__.py  2022-11-18 05:56:41.000000000 
+0100
@@ -4,7 +4,7 @@
     # setup.py and docs do not have Django installed.
     django = None
 
-VERSION = (3, 0, 0)
+VERSION = (3, 1, 0)
 __version__ = ".".join(str(i) for i in VERSION)
 
 if django and django.VERSION < (3, 2):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/taggit/managers.py 
new/django-taggit-3.1.0/taggit/managers.py
--- old/django-taggit-3.0.0/taggit/managers.py  2022-05-02 09:39:57.000000000 
+0200
+++ new/django-taggit-3.1.0/taggit/managers.py  2022-11-18 05:56:41.000000000 
+0100
@@ -142,9 +142,14 @@
     def _lookup_kwargs(self):
         return self.through.lookup_kwargs(self.instance)
 
+    def _remove_prefetched_objects(self):
+        prefetch_cache = getattr(self.instance, "_prefetched_objects_cache", 
None)
+        if prefetch_cache:
+            prefetch_cache.pop(self.prefetch_cache_name, None)
+
     @require_instance_manager
     def add(self, *tags, through_defaults=None, tag_kwargs=None, **kwargs):
-
+        self._remove_prefetched_objects()
         if tag_kwargs is None:
             tag_kwargs = {}
         db = router.db_for_write(self.through, instance=self.instance)
@@ -297,6 +302,7 @@
         if not tags:
             return
 
+        self._remove_prefetched_objects()
         db = router.db_for_write(self.through, instance=self.instance)
 
         qs = (
@@ -329,6 +335,7 @@
 
     @require_instance_manager
     def clear(self):
+        self._remove_prefetched_objects()
         db = router.db_for_write(self.through, instance=self.instance)
 
         signals.m2m_changed.send(
@@ -713,7 +720,7 @@
 
     # this is required to handle a change in Django 4.0
     # https://docs.djangoproject.com/en/4.0/releases/4.0/#miscellaneous
-    # the signature of the (private) funtion was changed
+    # the signature of the (private) function was changed
     if django.VERSION < (4, 0):
         get_extra_restriction = _get_extra_restriction_legacy
     else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/taggit/serializers.py 
new/django-taggit-3.1.0/taggit/serializers.py
--- old/django-taggit-3.0.0/taggit/serializers.py       2022-05-02 
09:39:57.000000000 +0200
+++ new/django-taggit-3.1.0/taggit/serializers.py       2022-11-18 
05:56:41.000000000 +0100
@@ -11,6 +11,11 @@
 
 
 class TagList(list):
+    """
+    This tag list subclass adds pretty printing support to the tag list
+    serializer
+    """
+
     def __init__(self, *args, **kwargs):
         pretty_print = kwargs.pop("pretty_print", True)
         super().__init__(*args, **kwargs)
@@ -33,7 +38,15 @@
             return json.dumps(self)
 
 
-class TagListSerializerField(serializers.Field):
+class TagListSerializerField(serializers.ListField):
+    """
+    A serializer field that can write out a tag list
+
+    This serializer field has some odd qualities compared to just using a 
ListField.
+    If this field poses problems, we should introduce a new field that is a 
simpler
+    ListField implementation with less features.
+    """
+
     child = serializers.CharField()
     default_error_messages = {
         "not_a_list": gettext_lazy(
@@ -59,6 +72,11 @@
         self.pretty_print = pretty_print
 
     def to_internal_value(self, value):
+        # note to future maintainers: this field used to not be a ListField
+        # and has extra behavior to support string-based input.
+        #
+        # In the future we should look at removing this feature so we can
+        # make this a simple ListField (if feasible)
         if isinstance(value, str):
             if not value:
                 value = "[]"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/tests/test_models.py 
new/django-taggit-3.1.0/tests/test_models.py
--- old/django-taggit-3.0.0/tests/test_models.py        2022-05-02 
09:39:57.000000000 +0200
+++ new/django-taggit-3.1.0/tests/test_models.py        2022-11-18 
05:56:41.000000000 +0100
@@ -25,3 +25,39 @@
             # unicode-ness will be kept by default
             sample_obj.tags.add("あい うえお")
             self.assertEqual([tag.slug for tag in sample_obj.tags.all()], [""])
+
+
+class TestPrefetchCache(TestCase):
+    def setUp(self) -> None:
+        sample_obj = TestModel.objects.create()
+        sample_obj.tags.set(["1", "2", "3"])
+
+    def test_cache_clears_on_add(self):
+        """
+        Test that the prefetch cache gets cleared on tag addition
+        """
+        sample_obj = TestModel.objects.prefetch_related("tags").get()
+        self.assertTrue(sample_obj.tags.is_cached(sample_obj))
+
+        sample_obj.tags.add("4")
+        self.assertFalse(sample_obj.tags.is_cached(sample_obj))
+
+    def test_cache_clears_on_remove(self):
+        """
+        Test that the prefetch cache gets cleared on tag removal
+        """
+        sample_obj = TestModel.objects.prefetch_related("tags").get()
+        self.assertTrue(sample_obj.tags.is_cached(sample_obj))
+
+        sample_obj.tags.remove("3")
+        self.assertFalse(sample_obj.tags.is_cached(sample_obj))
+
+    def test_cache_clears_on_clear(self):
+        """
+        Test that the prefetch cache gets cleared when tags are cleared
+        """
+        sample_obj = TestModel.objects.prefetch_related("tags").get()
+        self.assertTrue(sample_obj.tags.is_cached(sample_obj))
+
+        sample_obj.tags.clear()
+        self.assertFalse(sample_obj.tags.is_cached(sample_obj))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/tests/test_serializers.py 
new/django-taggit-3.1.0/tests/test_serializers.py
--- old/django-taggit-3.0.0/tests/test_serializers.py   2022-05-02 
09:39:57.000000000 +0200
+++ new/django-taggit-3.1.0/tests/test_serializers.py   2022-11-18 
05:56:41.000000000 +0100
@@ -5,8 +5,7 @@
 Tests for `django-taggit-serializer` models module.
 """
 
-import unittest
-
+from django.test import TestCase
 from rest_framework.exceptions import ValidationError
 
 from taggit import serializers
@@ -15,7 +14,7 @@
 from .serializers import TestModelSerializer
 
 
-class TestTaggit_serializer(unittest.TestCase):
+class TestTaggit_serializer(TestCase):
     def test_taggit_serializer_field(self):
         correct_value = ["1", "2", "3"]
         serializer_field = serializers.TagListSerializerField()
@@ -52,11 +51,24 @@
         request_data = {"tags": ["1", "2", "3"]}
 
         serializer = TestModelSerializer(data=request_data)
-        serializer.is_valid()
+        assert serializer.is_valid()
         test_model = serializer.save()
 
         assert len(test_model.tags.all()) == len(request_data.get("tags"))
 
+    def test_taggit_serializer_create_with_string(self):
+        """
+        Test that we can pass in a string instead of an array for
+        a tag list without issues
+        """
+        request_data = {"tags": '["1", "2", "3"]'}
+
+        serializer = TestModelSerializer(data=request_data)
+        assert serializer.is_valid(), serializer.errors
+        test_model = serializer.save()
+
+        assert set(tag.name for tag in test_model.tags.all()) == {"1", "2", 
"3"}
+
     def test_taggit_removes_tags(self):
         """
         Test if the old assigned tags are removed
@@ -72,3 +84,20 @@
 
         assert TestModel.objects.filter(tags__name__in=["1"]).count() == 0
         assert TestModel.objects.filter(tags__name__in=["1", "2"]).count() == 1
+
+    def test_returns_new_data_after_update(self):
+        """
+        Test if the serializer uses fresh data after updating prefetched fields
+        """
+        TestModel.objects.create().tags.add("1")
+
+        test_model = TestModel.objects.prefetch_related("tags").get()
+
+        assert TestModelSerializer(test_model).data["tags"] == ["1"]
+
+        request_data = {"tags": ["2", "3"]}
+        serializer = TestModelSerializer(test_model, data=request_data)
+        serializer.is_valid()
+        test_model = serializer.save()
+
+        assert set(serializer.data["tags"]) == {"2", "3"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/tests/tests.py 
new/django-taggit-3.1.0/tests/tests.py
--- old/django-taggit-3.0.0/tests/tests.py      2022-05-02 09:39:57.000000000 
+0200
+++ new/django-taggit-3.1.0/tests/tests.py      2022-11-18 05:56:41.000000000 
+0100
@@ -520,7 +520,7 @@
         pear = self.food_model.objects.create(name="pear")
         #   1 query to see which tags exist
         #   1  query to check existing ids for sending m2m_changed signal
-        # + 4 queries to create the intermeidary things (including SELECTs, to
+        # + 4 queries to create the intermediary things (including SELECTs, to
         #     make sure we dont't double create.
         # + 4 for save points.
         queries = 10
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-taggit-3.0.0/tox.ini 
new/django-taggit-3.1.0/tox.ini
--- old/django-taggit-3.0.0/tox.ini     2022-05-02 09:39:57.000000000 +0200
+++ new/django-taggit-3.1.0/tox.ini     2022-11-18 05:56:41.000000000 +0100
@@ -5,7 +5,8 @@
     flake8
     isort
     py{36,37,38,39,310}-dj32
-    py{38,39,310}-dj{40,main}
+    py{38,39,310}-dj40
+    py{38,39,310,311}-dj{41,main}
     docs
 
 [gh-actions]
@@ -15,11 +16,13 @@
     3.8: py38, black, flake8, isort
     3.9: py39
     3.10: py310
+    3.11: py311
 
 [testenv]
 deps =
     dj32: Django>=3.2,<3.3
     dj40: Django>=4.0,<4.1
+    dj41: Django>=4.1,<4.2
     djmain: https://github.com/django/django/archive/main.tar.gz
     coverage
     djangorestframework

Reply via email to