Search code examples
pythonmysqlconditional-statementspymysql

python 3.4 condition involving byte literal returns false instead of true


I use python 3.4 and pymysql connection to MySQL DB. I have a select query and then fetchall which returns results into r[]. r[0] is just the first part of the result tuple and its value is an empty string (as it should be based on what is in the DB.)

However, when I use the condition:

if str(r[0]) == ''.encode('utf8'):
        do something...

the condition evaluates to false, instead of what I was expecting it to be true! I test it to figure out why by printing out the values of the part:

    print(str(r[0]))
    print(''.encode('utf8')) 
    print(str(r[0]) == ''.encode('utf8'))  

This prints:

b''
b''
False

Any idea why? This is driving me nuts, because it should not be this hard. What am I missing?


Solution

  • You're comparing bytes and unicode and this is bound to always compare to False in Python 3. Some references:

    http://scikit-bio.org/docs/0.1.3/development/py3.html#gotchas

    http://lucumr.pocoo.org/2013/7/2/the-updated-guide-to-unicode/

    The solution is not to call encode() on your empty string on the right hand side:

    Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
    [GCC 4.9.1] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> str(r[0]) == ''
    True
    

    As you can see, the result of encode() on an str object are bytes:

    >>> x = ''.encode('utf8')
    >>> type(x)
    <class 'bytes'>