Wednesday, February 25, 2015

Re: TypeError: __str__ returned non-string (type bytes)

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

On Feb 24, 2015 8:33 PM, "Mike Dewhirst" <miked@dewhirst.com.au> wrote:
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)



--
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-users@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.

--
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-users@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/CA%2Be%2BciVZOsEBmy%3D3dBrutJPAhJ2f0ERhc6bs0OLk7BJrO2%3D%3D-w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment