TypeError: __str__ returned non-string (type bytes)

598 views
Skip to first unread message

Mike Dewhirst

unread,
Feb 24, 2015, 11:34:34 PM2/24/15
to django...@googlegroups.com
This is driving me insane so any hints will be greatly appreciated ...

Thanks

Mike

Here is the entire unedited test sequence plus failing code ...

Python: 3.4
Django: 1.6.9
SQLite3: memory

Creating test database for alias 'default'...
.E.E...
======================================================================
ERROR: test_checkreference_exp
(substance.tests.test_substance.TestSubstance)
----------------------------------------------------------------------
Traceback (most recent call last):
File
"C:\Users\mike\env\xxdx3\ssds\substance\tests\test_substance.py", line
57, in test_checkreference_exp
self.assertEqual(subst.checkreference('1'), True)
File "C:\Users\mike\env\xxdx3\ssds\substance\models\substance.py",
line 449, in checkreference
if checkit(self, ref):
File "C:\Users\mike\env\xxdx3\ssds\substance\models\substance.py",
line 441, in checkit
val = u"{0}".format(obj.__dict__[field])
TypeError: __str__ returned non-string (type bytes)

======================================================================
ERROR: testcheckreference_gas (substance.tests.test_substance.TestSubstance)
----------------------------------------------------------------------
Traceback (most recent call last):
File
"C:\Users\mike\env\xxdx3\ssds\substance\tests\test_substance.py", line
75, in test_checkreference_gas
self.assertEqual(subst.checkreference('1'.encode('utf-8')), True)
File "C:\Users\mike\env\xxdx3\ssds\substance\models\substance.py",
line 449, in checkreference
if checkit(self, ref):
File "C:\Users\mike\env\xxdx3\ssds\substance\models\substance.py",
line 441, in checkit
val = u"{0}".format(obj.__dict__[field])
TypeError: __str__ returned non-string (type bytes)

----------------------------------------------------------------------
Ran 7 tests in 1.281s

FAILED (errors=2)
Destroying test database for alias 'default'...

So here is the method in the substance model. The idea is that we check
to see if the user included a bracketed reference in any field of
substance or any field of a related object. I'll chop out the middle of
the method to save space.

def checkreference(self, ref):
"""Check all potential char fields for ref in square brackets
eg [1]

Give up as soon as it is found. Otherwise raise validation error.
"""
def checkit(obj, ref):
"""Return True immediately but don't return False unless all
fields have been checked."""
for field in obj.__dict__:
val = u"{0}".format(obj.__dict__[field])
if ref in val:
return True

assert(ref)
ref = "[{0}]".format(ref)
# first check self - the substance itself
if checkit(self, ref):
return True
# now each of the 1:1 and 1:n objects
try:
obj = Solid.objects.get(substance=self)
if checkit(obj, ref):
return True
except Solid.DoesNotExist:
pass
<snip lots of similar try/except blocks>
raise ValidationError("Reference {0} does not appear in any "
"field".format(ref))

... and here is one of the tests (line 57 in the traceback) in error ...

def test_checkreference_exp(self):
subst = Substance.objects.get(name="Hazsub")
exp, c = Explosive.objects.get_or_create(substance=subst)
exp.compatibility = '[1]'
exp.save()
self.assertEqual(subst.checkreference('1'), True)



James Schneider

unread,
Feb 25, 2015, 4:04:23 AM2/25/15
to django...@googlegroups.com

What happens when you throw in a print(obj.__dict__[field]) before the val assignment? You should see on the console what value each iteration of the loop is using and see if you have a strange attribute that is throwing things out of kilter.

-James

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/54ED50A5.3030909%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

Erik Cederstrand

unread,
Feb 25, 2015, 5:08:45 AM2/25/15
to Django Users

> Den 25/02/2015 kl. 05.33 skrev Mike Dewhirst <mi...@dewhirst.com.au>:
>
> ======================================================================
> ERROR: test_checkreference_exp (substance.tests.test_substance.TestSubstance)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
> File "C:\Users\mike\env\xxdx3\ssds\substance\tests\test_substance.py", line 57, in test_checkreference_exp
> self.assertEqual(subst.checkreference('1'), True)
> File "C:\Users\mike\env\xxdx3\ssds\substance\models\substance.py", line 449, in checkreference
> if checkit(self, ref):
> File "C:\Users\mike\env\xxdx3\ssds\substance\models\substance.py", line 441, in checkit
> val = u"{0}".format(obj.__dict__[field])
> TypeError: __str__ returned non-string (type bytes)

"obj.__dict__[field]" returns an object that has a __str__ method (format() calls the __str__ method of the object to convert it to a string). The __str__ method should only return unicode data but is returning byte strings. What does "obj.__dict__[field]" return, and can you show us the __str__ method of that class?

Erik

Mike Dewhirst

unread,
Feb 25, 2015, 6:56:02 PM2/25/15
to django...@googlegroups.com
Erik and James

I really appreciate your feedback. The problem is resolved. It was related to py3 development and py2 in production. Erik had hit the nail on the head which I discovered when I went looking at why other tests were passing and those two were not. I had been inconsistent in implementing @python_2_unicode_compatible

Thank you again

Mike
Reply all
Reply to author
Forward
0 new messages