summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_compile.py
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2024-09-25 14:51:25 (GMT)
committerGitHub <noreply@github.com>2024-09-25 14:51:25 (GMT)
commit78aeb38f7d880a340295214abc4f7e77ffdad509 (patch)
tree8944d52302e56f98bef775d2599c6eee3c4db3b6 /Lib/test/test_compile.py
parentc58c572a65eb5b93d054e779df289e975a0b9864 (diff)
downloadcpython-78aeb38f7d880a340295214abc4f7e77ffdad509.zip
cpython-78aeb38f7d880a340295214abc4f7e77ffdad509.tar.gz
cpython-78aeb38f7d880a340295214abc4f7e77ffdad509.tar.bz2
gh-124285: Fix bug where bool() is called multiple times for the same part of a boolean expression (#124394)
Diffstat (limited to 'Lib/test/test_compile.py')
-rw-r--r--Lib/test/test_compile.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 736eff3..b81d847 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1527,6 +1527,45 @@ class TestSpecifics(unittest.TestCase):
pass
[[]]
+class TestBooleanExpression(unittest.TestCase):
+ class Value:
+ def __init__(self):
+ self.called = 0
+
+ def __bool__(self):
+ self.called += 1
+ return self.value
+
+ class Yes(Value):
+ value = True
+
+ class No(Value):
+ value = False
+
+ def test_short_circuit_and(self):
+ v = [self.Yes(), self.No(), self.Yes()]
+ res = v[0] and v[1] and v[0]
+ self.assertIs(res, v[1])
+ self.assertEqual([e.called for e in v], [1, 1, 0])
+
+ def test_short_circuit_or(self):
+ v = [self.No(), self.Yes(), self.No()]
+ res = v[0] or v[1] or v[0]
+ self.assertIs(res, v[1])
+ self.assertEqual([e.called for e in v], [1, 1, 0])
+
+ def test_compound(self):
+ # See gh-124285
+ v = [self.No(), self.Yes(), self.Yes(), self.Yes()]
+ res = v[0] and v[1] or v[2] or v[3]
+ self.assertIs(res, v[2])
+ self.assertEqual([e.called for e in v], [1, 0, 1, 0])
+
+ v = [self.No(), self.No(), self.Yes(), self.Yes(), self.No()]
+ res = v[0] or v[1] and v[2] or v[3] or v[4]
+ self.assertIs(res, v[3])
+ self.assertEqual([e.called for e in v], [1, 1, 0, 1, 0])
+
@requires_debug_ranges()
class TestSourcePositions(unittest.TestCase):
# Ensure that compiled code snippets have correct line and column numbers