Repository: jazzband/django-taggit (language: python)

Issue:
Test suite fails if unidecode is installed
```
$ python --version
Python 3.11.3
$ pip list
Package             Version
------------------- -------
asgiref             3.6.0
coverage            7.2.5
Django              4.2.1
django-taggit       4.0.0
djangorestframework 3.14.0
pip                 23.0.1
pytz                2023.3
setuptools          67.6.1
sqlparse            0.4.4
Unidecode           1.3.6
wheel               0.40.0
$ python -m django test --settings=tests.settings
Found 378 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.............F.........................................................................................................s.................................s.................................s.................................s...................................s......................................................................s.................................s...............
======================================================================
FAIL: test_old_slugs (tests.test_models.TestSlugification.test_old_slugs)
Test that the setting that gives us the old slugification behavior
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/django-taggit-4.0.0/tests/test_models.py", line 27, in test_old_slugs
    self.assertEqual([tag.slug for tag in sample_obj.tags.all()], [""])
AssertionError: Lists differ: ['ai-ueo'] != ['']

First differing element 0:
'ai-ueo'
''

- ['ai-ueo']
+ ['']

----------------------------------------------------------------------
Ran 378 tests in 8.998s

FAILED (failures=1, skipped=7)
Destroying test database for alias 'default'...
```


Discussion / hints:
Gentle ping. Can we either mock the code, so that it ignores `unidecode`, or skip it if unidecode's installed?

Fix patch:
diff --git a/taggit/models.py b/taggit/models.py
index 0b14e7d9..8e981a08 100644
--- a/taggit/models.py
+++ b/taggit/models.py
@@ -9,9 +9,20 @@
 
 try:
     from unidecode import unidecode
+
+    unidecode_installed = True
 except ImportError:
+    unidecode_installed = False
+
 
-    def unidecode(tag):
+def slugify_unicode_stripping_prep(tag):
+    """
+    This handles stripping via unidecode if it's installed,
+    otherwise is a no-op
+    """
+    if unidecode_installed:
+        return unidecode(tag)
+    else:
         return tag
 
 
@@ -97,7 +108,7 @@ def save(self, *args, **kwargs):
 
     def slugify(self, tag, i=None):
         if getattr(settings, "TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING", False):
-            slug = slugify(unidecode(tag))
+            slug = slugify(slugify_unicode_stripping_prep(tag))
         else:
             slug = slugify(tag, allow_unicode=True)
         if i is not None:
diff --git a/tox.ini b/tox.ini
index af630a80..ff642c5e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -24,6 +24,7 @@ deps =
     djmain: https://github.com/django/django/archive/main.tar.gz
     coverage
     djangorestframework
+    unidecode
 setenv =
     PYTHONWARNINGS=all
 commands =


Test patch:
diff --git a/tests/test_models.py b/tests/test_models.py
index 4a9b748c..1d356d99 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -1,8 +1,25 @@
+from contextlib import contextmanager
+from unittest import skipIf
+
 from django.test import TestCase, override_settings
 
+from taggit import models as taggit_models
 from tests.models import TestModel
 
 
+@contextmanager
+def disable_unidecode():
+    """
+    Disable unidecode temporarily
+    """
+    old_installed_value = taggit_models.unidecode_installed
+    taggit_models.unidecode_installed = False
+    try:
+        yield
+    finally:
+        taggit_models.unidecode_installed = old_installed_value
+
+
 class TestTaggableManager(TestCase):
     def test_duplicates(self):
         sample_obj = TestModel.objects.create()
@@ -22,17 +39,35 @@ def test_unicode_slugs(self):
         sample_obj.tags.add("あい うえお")
         self.assertEqual([tag.slug for tag in sample_obj.tags.all()], ["あい-うえお"])
 
-    def test_old_slugs(self):
+    def test_old_slugs_wo_unidecode(self):
+        """
+        Test that the setting that gives us the old slugification behavior
+        is in place
+        """
+        with (
+            disable_unidecode(),
+            override_settings(TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING=True),
+        ):
+            sample_obj = TestModel.objects.create()
+            sample_obj.tags.add("aあい うえおb")
+            # when unidecode is not installed, the unicode ends up being passed directly
+            # to slugify, and will get "wiped"
+            self.assertEqual([tag.slug for tag in sample_obj.tags.all()], ["a-b"])
+
+    @skipIf(
+        not taggit_models.unidecode_installed,
+        "This test requires unidecode to be installed",
+    )
+    def test_old_slugs_with_unidecode(self):
         """
         Test that the setting that gives us the old slugification behavior
         is in place
         """
         with override_settings(TAGGIT_STRIP_UNICODE_WHEN_SLUGIFYING=True):
             sample_obj = TestModel.objects.create()
-            # a unicode tag will be slugified for space reasons but
-            # unicode-ness will be kept by default
+            # unidecode will transform the tag on top of slugification
             sample_obj.tags.add("あい うえお")
-            self.assertEqual([tag.slug for tag in sample_obj.tags.all()], [""])
+            self.assertEqual([tag.slug for tag in sample_obj.tags.all()], ["ai-ueo"])
 
 
 class TestPrefetchCache(TestCase):