I noticed that multiple threads calling get__raw for inertial sensors would be returned a self.last dictionary. A user can modify this dictionary and if self._get_raw_data returns None on subsequent calls to the method, then the user will be returned the modified dictionary. I proposed some changes that return deep copies to prevent users from accidentally modifying underlying class dictionaries that may cause this type of behavior.
Here is a specific example and stack trace from calling get_orientation_degrees(). If one thread calls get_orientation_radians(), they are returned a shallow copy of the class dictionary that could also be returned by get_orientation_degrees(). This can happen if self._get_raw_data('fusionPoseValid', 'fusionPose') returns None in the get_orientation_radians() method. If the user has modified the dictionary, then get_orientation_degrees() can be returned the modified dictionary. This can result in exceptions or other errors. As an example, deg = Math.degrees(val) can raise a TypeError exception if a non-float value has been added to the self._last_orientation dictionary before get_orientation_degrees() was called. Here is a stack trace:
Exception in thread Thread-7:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(_self.args, *_self.__kwargs)
File "sensor_collector.py", line 262, in stream_orientation_degrees_data
payload = self.sense.get_orientation_degrees()
File "/usr/lib/python2.7/dist-packages/sense_hat/sense_hat.py", line 732, in get_orientation_degrees
deg = math.degrees(val) # Result is -180 to +180
TypeError: a float is required
I noticed that multiple threads calling get__raw for inertial sensors would be returned a self.last dictionary. A user can modify this dictionary and if self._get_raw_data returns None on subsequent calls to the method, then the user will be returned the modified dictionary. I proposed some changes that return deep copies to prevent users from accidentally modifying underlying class dictionaries that may cause this type of behavior.
Here is a specific example and stack trace from calling get_orientation_degrees(). If one thread calls get_orientation_radians(), they are returned a shallow copy of the class dictionary that could also be returned by get_orientation_degrees(). This can happen if self._get_raw_data('fusionPoseValid', 'fusionPose') returns None in the get_orientation_radians() method. If the user has modified the dictionary, then get_orientation_degrees() can be returned the modified dictionary. This can result in exceptions or other errors. As an example, deg = Math.degrees(val) can raise a TypeError exception if a non-float value has been added to the self._last_orientation dictionary before get_orientation_degrees() was called. Here is a stack trace:
Exception in thread Thread-7: Traceback (most recent call last): File "/usr/lib/python2.7/threading.py", line 810, in bootstrap_inner self.run() File "/usr/lib/python2.7/threading.py", line 763, in run self.__target(_self.args, *_self.__kwargs) File "sensor_collector.py", line 262, in stream_orientation_degrees_data payload = self.sense.get_orientation_degrees() File "/usr/lib/python2.7/dist-packages/sense_hat/sense_hat.py", line 732, in get_orientation_degrees deg = math.degrees(val) # Result is -180 to +180 TypeError: a float is required