pyscript
pyscript copied to clipboard
Boolean operators return the wrong type
Whilst trying to make a battery sensor, I stumbled on some very strange behaviour (I'm doing this in a Jupyter notebook using https://github.com/craigbarratt/hass-pyscript-jupyter).
The script at the top should return an empty list, but instead it returns a list. I explored further and there seems to be something strange about the boolean and operator. Here is what's in my notebook:
import re
state_names = ['sun.sun', 'group.battery_level', 'group.battery_alert', 'input_number.battery_alert_threshold_max']
ignore_sensors = ["sun.sun", "group.battery_level"]
[sensor for sensor in state_names if (re.search(r'_battery(_level)?$', sensor) and (sensor not in ignore_sensors))]
['group.battery_alert', 'input_number.battery_alert_threshold_max']
[re.search('battery', sensor) and sensor not in ignore_sensors for sensor in state_names]
[0, 0, True, True]
type(True and False)
<class 'int'>
type(False)
<class 'bool'>
type(True)
<class 'bool'>
type(True and True)
<class 'bool'>
type(True and True)
<class 'bool'>
bool(0)
False
Checked out https://github.com/custom-components/pyscript/blob/master/custom_components/pyscript/eval.py#L1678 and it seems the following "logic" applies for A and B:
- if
AorBis false-ish anintwith value0is returned - if
AandBare true-ish, thenBis returned
Would seem sensible to return a bool False or True instead of 0 and something that happened to be on the right side of and. But Python https://docs.python.org/3/reference/expressions.html#boolean-operations says:
The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.
So if A == 0 then it's correct to return 0. But if A == False, then the and should return False and not 0.
Thanks for finding and reporting the bug. I just pushed a fix. If you get a chance, please test it to make sure it resolves your test cases. I'll add some test cases too.
This is fixed in 1.4.0. Closing.