studioimaginaire / phue

A Python library for the Philips Hue system
Other
1.52k stars 267 forks source link

Reverted `e5e550bf` `decodeString` in Bridge.request #149

Closed blacklight closed 5 years ago

blacklight commented 5 years ago

In Python 3 httplib.HTTPConnection.getresponse().read() returns a bytes stream, not a string. Therefore commit e5e550bf broke the request parsing on Python 3:

>>> from phue import Bridge
>>> b = Bridge('hue')
>>> b.get_scene()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/blacklight/git_tree/phue/phue.py", line 1128, in get_scene
    return self.request('GET', '/api/' + self.username + '/scenes')
  File "/home/blacklight/git_tree/phue/phue.py", line 666, in request
    return json.loads(decodeString(response))
  File "/usr/lib/python3.5/json/__init__.py", line 312, in loads
    s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'
natcl commented 5 years ago

What version of Python 3 are you using ? On my side it works with Python 3.6

blacklight commented 5 years ago

Python 3.5.3 in my example (that's still the default Python 3 version on Debian/Raspbian/TinkerOS).

Not sure how it can work on Python >= 3.6 however. Even on the most recent versions http.client would return bytes, not string, that need to be decode (just tested on Python 3.7):

>>> import http.client as httplib
>>> connection = httplib.HTTPConnection('www.google.com')
>>> connection.request('GET', '/')
>>> result = connection.getresponse()
>>> response = result.read()
>>> type(response)
<class 'bytes'>
natcl commented 5 years ago

I'll have a look tonight on Python 3.5 Problem is before the fix it would fail in Python 2.x with accented characters.

-- lecaude.com studioimaginaire.com

Le 27 janv. 2019 à 14:20, Fabio Manganiello notifications@github.com a écrit :

Python 3.5.3 in my example (that's still the default Python 3 version on Debian/Raspbian/TinkerOS).

Not sure how it can work on Python >= 3.6 however. Even on the most recent versions http.client would return bytes, not string, that need to be decode (just tested on Python 3.7):

import http.client as httplib connection = httplib.HTTPConnection('www.google.com') connection.request('GET', '/') result = connection.getresponse() response = result.read() type(response) <class 'bytes'> — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

blacklight commented 5 years ago

My PR should still work fine on Python 2, as my change only modifies the behaviour when decoding the response on Python 3 and it shouldn't change anything on Python 2.

natcl commented 5 years ago

I just tried the above code in both Python 2.7 and Python 3.6 on a Mac and I don't get errors, what version of the Bridge are you using ? I only have the old bridge, is it possible they behave in a different manner ?

natcl commented 5 years ago

Update: This is a bug that happens only in python 3.5, works fine in python 3.6 and above so I'll probably add a check just for python 3.5.... Seems silly though as this seems like a bug specific only to that version.

natcl commented 5 years ago

Seems like this is why it works in 3.6 and above: https://docs.python.org/3/whatsnew/3.6.html#json

natcl commented 5 years ago

Ok merging as this fixes it for all versions, thanks