Opened 8 years ago
Closed 8 years ago
#28772 closed Cleanup/optimization (wontfix)
UnicodeWarning produced when using callable default on BinaryField in Python 2
| Reported by: | Tim Dawborn | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 1.8 |
| Severity: | Normal | Keywords: | UnicodeWarning BinaryField |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | yes | UI/UX: | no |
Description
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):
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:
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
Change History (1)
comment:1 by , 8 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
| Type: | Uncategorized → Cleanup/optimization |
#23222 is related. As Django's master branch (and the upcoming 2.0 release) no longer support Python 2 and this issue doesn't qualify for a backport to 1.11 as per our supported versions policy, we won't fix it.