#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.