Opened 7 years ago
Closed 7 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 , 7 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.