#33724: Django 4.1 alpha - changing from list to set in `exclude` raises errors,
and is not documented
-----------------------------------------+------------------------
               Reporter:  אורי           |          Owner:  nobody
                   Type:  Uncategorized  |         Status:  new
              Component:  Uncategorized  |        Version:  4.1
               Severity:  Normal         |       Keywords:
           Triage Stage:  Unreviewed     |      Has patch:  0
    Needs documentation:  0              |    Needs tests:  0
Patch needs improvement:  0              |  Easy pickings:  0
                  UI/UX:  0              |
-----------------------------------------+------------------------
 The commit:
 
https://github.com/django/django/commit/1ea7e3157d1f9b4db71e768d75ea57e47dbd49f9

 My use case:

 I used `def clean_fields` in a mixin inherited by some of my models:

 {{{
 class CleanAndValidateAllFieldsMixin(object):
     def clean_fields(self, exclude=None):
         """
         Allows to have different slug and username validators for Entity
 and User.
         """
         if (exclude is None):
             exclude = []

         self.clean_all_fields(exclude=exclude)

         try:
             super().clean_fields(exclude=exclude)
         except ValidationError as e:
             errors = e.error_dict
         else:
             errors = {}

         self.validate_all_fields(errors=errors, exclude=exclude)

     def clean_all_fields(self, exclude=None):
         pass

 }}}

 In some of the models that use it, I defined `clean_fields` and added
 values to `exclude`:

 {{{
     def clean_fields(self, exclude=None):
         self.normalize_slug_and_username()
         self.validate_username_for_slug()
         self.validate_username_required()
         self.validate_username_unique()

         if (exclude is None):
             exclude = []

         # Reserved username can be less than 6 characters, and any
 alphanumeric sequence.
         exclude += ['username', 'slug']

         return super().clean_fields(exclude=exclude)
 }}}

 {{{
     def clean_fields(self, exclude=None):
         """
         Allows to have different slug and username validators for Entity
 and User.
         """
         if (exclude is None):
             exclude = []

         # If special username is true, don't validate username.
         if (self.special_username):
             self.normalize_slug_and_username()
             self.validate_username_for_slug()
             self.validate_username_required()
             self.validate_username_unique()
             exclude += ['username', 'slug']

         return super().clean_fields(exclude=exclude)
 }}}

 The results: model tests fail with Django 4.1 alpha:

 {{{
 ======================================================================
 ERROR: test_username_too_long_exception_4
 (speedy.core.accounts.tests.test_models.ReservedUsernameHebrewTestCase)
 ----------------------------------------------------------------------
 Traceback (most recent call last):
   File "...\speedy\core\accounts\tests\test_models.py", line 395, in
 test_username_too_long_exception_4
     reserved_username.save()
   File "...\speedy\core\base\models.py", line 21, in save
     return super().save(*args, **kwargs)
   File "...\speedy\core\base\models.py", line 12, in save
     self.full_clean()
   File "...\.venv_3.9\lib\site-packages\django\db\models\base.py", line
 1464, in full_clean
     self.clean_fields(exclude=exclude)
   File "...\speedy\core\accounts\models.py", line 182, in clean_fields
     exclude += ['username', 'slug']
 TypeError: unsupported operand type(s) for +=: 'set' and 'list'

 ----------------------------------------------------------------------
 }}}

 Is `exclude` a set now (instead of a list) and where is it documented? If
 it's not documented, please document it. I didn't find it documented on
 https://docs.djangoproject.com/en/dev/releases/4.1/.

 What is the best written code to change the line `exclude += ['username',
 'slug']` in my code? Is it `exclude |= set(['username', 'slug'])` or
 `exclude |= {'username', 'slug'}`? Or should I convert to list and then
 back to set?

 What is the reason `exclude` was changed to a set?

 How should `exclude` be defined in `clean_fields` and what should I do if
 I receive `exclude is None`?

 Thanks,
 Uri.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33724>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070180db8b14db-9e192696-f136-40e9-abfd-da425d32ee36-000000%40eu-central-1.amazonses.com.

Reply via email to