#28772: UnicodeWarning produced when using callable default on BinaryField in
Python 2
-------------------------------------+-------------------------------------
               Reporter:  Tim        |          Owner:  nobody
  Dawborn                            |
                   Type:             |         Status:  new
  Uncategorized                      |
              Component:  Database   |        Version:  1.8
  layer (models, ORM)                |       Keywords:  UnicodeWarning
               Severity:  Normal     |  BinaryField
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  1
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 This affects versions all the way back from 1.8 and the rest of the 1.x
 series (the issue tracker only lets me go back to 1.8). This only happens
 when running under Python 2.

 When using a callable `default` value to a `BinaryField` instance, a
 `UnicodeWarning` is produced due to the comparison of the return value of
 `default` against a Unicode string (from
 
https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L2306):

 {{{#!python
 class BinaryField(Field):
     ...
     def get_default(self):
         if self.has_default() and not callable(self.default):
             return self.default
         default = super(BinaryField, self).get_default()
         if default == '':
             return b''
         return default
 }}}


 I've created a blank Django project called `foo` and created an app called
 `bar`. In there, I've created a model called `Baz` which has a
 `BinaryField` with a callable default.

 {{{
 $ cat bar/models.py
 import os

 from django.db import models


 def my_default():
     return os.urandom(12)


 class Baz(models.Model):
     my_field = models.BinaryField(default=my_default)
 }}}

 I have two virtualenvs setup — one running Python 2.7 and one running 3.6.
 Both have Django 1.11 installed:
 {{{
 $ ../ve2/bin/pip install -q --upgrade 'django<2'
 $ ../ve3/bin/pip install -q --upgrade 'django<2'
 }}}

 When running under Python 2, Django versions 1.8 through 1.11 (all minor
 versions inclusive) produce a `UnicodeWarning` when deprecation warnings
 are enabled:
 {{{
 $ ../ve2/bin/python -W default manage.py shell -c 'from bar.models import
 Baz; b = Baz()'
 /private/tmp/django/ve2/lib/python2.7/site-
 packages/django/db/models/fields/__init__.py:2343: UnicodeWarning: Unicode
 equal comparison failed to convert both arguments to Unicode -
 interpreting them as being unequal
   if default == '':
 $ ../ve3/bin/python -W default manage.py shell -c 'from bar.models import
 Baz; b = Baz()'
 $
 }}}

 This could be fixed by doing a type check on the returned value of the
 callable to see if it is of type `six.text_type` a la
 https://docs.djangoproject.com/en/1.11/topics/python3/#string-handling-
 with-six:
 {{{#!python
 class BinaryField(Field):
     ...
     def get_default(self):
         if self.has_default() and not callable(self.default):
             return self.default
         default = super(BinaryField, self).get_default()
         if isinstance(default, six.text_type) and default == '':
             return b''
         return default
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28772>
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/053.7b2949c0e01a414ea35cc74f0ff6fadb%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to