Skip to content

Commit 0d9f936

Browse files
jgarzikclaude
andcommitted
Import test_controlflow, test_math_basic, test_global_nonlocal, test_unpacking, test_inheritance
New tests: - test_controlflow.py: 23 tests — if/elif/else, while, for, break/continue, while/for-else, ternary, pass, nested loops - test_math_basic.py: 25 tests — int/float/bool arithmetic, bitwise ops, abs, divmod, large ints, mixed-type arithmetic - test_global_nonlocal.py: 12 tests — global/nonlocal statements, enclosing scope, class scope, comprehension scope isolation - test_unpacking.py: 14 tests, 3 skips — tuple/list unpacking, star unpacking, nested unpacking, swap, for-loop star unpacking - test_inheritance.py: 13 tests — single inheritance, super(), method resolution, isinstance/issubclass chains, exception inheritance Total CPython test suites: 47 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2e674b6 commit 0d9f936

6 files changed

Lines changed: 703 additions & 0 deletions

File tree

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ gen-cpython-tests:
140140
@$(PYTHON) -m py_compile tests/cpython/test_set_extra.py
141141
@echo "Compiling tests/cpython/test_list_extra.py..."
142142
@$(PYTHON) -m py_compile tests/cpython/test_list_extra.py
143+
@echo "Compiling tests/cpython/test_controlflow.py..."
144+
@$(PYTHON) -m py_compile tests/cpython/test_controlflow.py
145+
@echo "Compiling tests/cpython/test_math_basic.py..."
146+
@$(PYTHON) -m py_compile tests/cpython/test_math_basic.py
147+
@echo "Compiling tests/cpython/test_global_nonlocal.py..."
148+
@$(PYTHON) -m py_compile tests/cpython/test_global_nonlocal.py
149+
@echo "Compiling tests/cpython/test_unpacking.py..."
150+
@$(PYTHON) -m py_compile tests/cpython/test_unpacking.py
151+
@echo "Compiling tests/cpython/test_inheritance.py..."
152+
@$(PYTHON) -m py_compile tests/cpython/test_inheritance.py
143153
@echo "Done."
144154

145155
check-cpython: $(TARGET) gen-cpython-tests
@@ -227,3 +237,13 @@ check-cpython: $(TARGET) gen-cpython-tests
227237
@./apython tests/cpython/__pycache__/test_set_extra.cpython-312.pyc
228238
@echo "Running CPython test_list_extra.py..."
229239
@./apython tests/cpython/__pycache__/test_list_extra.cpython-312.pyc
240+
@echo "Running CPython test_controlflow.py..."
241+
@./apython tests/cpython/__pycache__/test_controlflow.cpython-312.pyc
242+
@echo "Running CPython test_math_basic.py..."
243+
@./apython tests/cpython/__pycache__/test_math_basic.cpython-312.pyc
244+
@echo "Running CPython test_global_nonlocal.py..."
245+
@./apython tests/cpython/__pycache__/test_global_nonlocal.cpython-312.pyc
246+
@echo "Running CPython test_unpacking.py..."
247+
@./apython tests/cpython/__pycache__/test_unpacking.cpython-312.pyc
248+
@echo "Running CPython test_inheritance.py..."
249+
@./apython tests/cpython/__pycache__/test_inheritance.cpython-312.pyc

tests/cpython/test_controlflow.py

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
"""Tests for control flow — if/elif/else, while, for, break, continue, pass"""
2+
3+
import unittest
4+
5+
6+
class IfTest(unittest.TestCase):
7+
8+
def test_basic_if(self):
9+
x = 10
10+
if x > 5:
11+
result = "big"
12+
else:
13+
result = "small"
14+
self.assertEqual(result, "big")
15+
16+
def test_elif(self):
17+
def classify(x):
18+
if x < 0:
19+
return "negative"
20+
elif x == 0:
21+
return "zero"
22+
elif x < 10:
23+
return "small"
24+
else:
25+
return "big"
26+
self.assertEqual(classify(-5), "negative")
27+
self.assertEqual(classify(0), "zero")
28+
self.assertEqual(classify(5), "small")
29+
self.assertEqual(classify(100), "big")
30+
31+
def test_nested_if(self):
32+
def f(x, y):
33+
if x > 0:
34+
if y > 0:
35+
return "both positive"
36+
else:
37+
return "x positive"
38+
else:
39+
return "x not positive"
40+
self.assertEqual(f(1, 1), "both positive")
41+
self.assertEqual(f(1, -1), "x positive")
42+
self.assertEqual(f(-1, 1), "x not positive")
43+
44+
def test_ternary(self):
45+
self.assertEqual("yes" if True else "no", "yes")
46+
self.assertEqual("yes" if False else "no", "no")
47+
x = 10
48+
self.assertEqual("big" if x > 5 else "small", "big")
49+
50+
51+
class WhileTest(unittest.TestCase):
52+
53+
def test_basic_while(self):
54+
n = 0
55+
while n < 10:
56+
n += 1
57+
self.assertEqual(n, 10)
58+
59+
def test_while_break(self):
60+
n = 0
61+
while True:
62+
n += 1
63+
if n == 5:
64+
break
65+
self.assertEqual(n, 5)
66+
67+
def test_while_continue(self):
68+
result = []
69+
n = 0
70+
while n < 10:
71+
n += 1
72+
if n % 2 == 0:
73+
continue
74+
result.append(n)
75+
self.assertEqual(result, [1, 3, 5, 7, 9])
76+
77+
def test_while_else(self):
78+
hit_else = False
79+
n = 0
80+
while n < 3:
81+
n += 1
82+
else:
83+
hit_else = True
84+
self.assertTrue(hit_else)
85+
86+
def test_while_else_break(self):
87+
hit_else = False
88+
n = 0
89+
while n < 10:
90+
n += 1
91+
if n == 5:
92+
break
93+
else:
94+
hit_else = True
95+
self.assertFalse(hit_else)
96+
97+
98+
class ForTest(unittest.TestCase):
99+
100+
def test_for_range(self):
101+
total = 0
102+
for i in range(10):
103+
total += i
104+
self.assertEqual(total, 45)
105+
106+
def test_for_list(self):
107+
result = []
108+
for x in [1, 2, 3]:
109+
result.append(x * 2)
110+
self.assertEqual(result, [2, 4, 6])
111+
112+
def test_for_string(self):
113+
chars = []
114+
for c in "hello":
115+
chars.append(c)
116+
self.assertEqual(chars, ['h', 'e', 'l', 'l', 'o'])
117+
118+
def test_for_dict(self):
119+
d = {'a': 1, 'b': 2}
120+
keys = []
121+
for k in d:
122+
keys.append(k)
123+
self.assertEqual(sorted(keys), ['a', 'b'])
124+
125+
def test_for_tuple_unpack(self):
126+
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
127+
nums = []
128+
chars = []
129+
for n, c in pairs:
130+
nums.append(n)
131+
chars.append(c)
132+
self.assertEqual(nums, [1, 2, 3])
133+
self.assertEqual(chars, ['a', 'b', 'c'])
134+
135+
def test_nested_for(self):
136+
result = []
137+
for i in range(3):
138+
for j in range(3):
139+
if i == j:
140+
result.append(i)
141+
self.assertEqual(result, [0, 1, 2])
142+
143+
def test_for_break(self):
144+
found = -1
145+
for i in range(100):
146+
if i * i > 50:
147+
found = i
148+
break
149+
self.assertEqual(found, 8)
150+
151+
def test_for_continue(self):
152+
evens = []
153+
for i in range(10):
154+
if i % 2 != 0:
155+
continue
156+
evens.append(i)
157+
self.assertEqual(evens, [0, 2, 4, 6, 8])
158+
159+
def test_for_else(self):
160+
hit = False
161+
for i in range(5):
162+
pass
163+
else:
164+
hit = True
165+
self.assertTrue(hit)
166+
167+
def test_for_else_break(self):
168+
hit = False
169+
for i in range(5):
170+
if i == 3:
171+
break
172+
else:
173+
hit = True
174+
self.assertFalse(hit)
175+
176+
177+
class PassTest(unittest.TestCase):
178+
179+
def test_pass_in_if(self):
180+
if True:
181+
pass
182+
self.assertTrue(True)
183+
184+
def test_pass_in_class(self):
185+
class Empty:
186+
pass
187+
self.assertIsNotNone(Empty)
188+
189+
def test_pass_in_function(self):
190+
def f():
191+
pass
192+
self.assertIsNone(f())
193+
194+
def test_pass_in_loop(self):
195+
for i in range(5):
196+
pass
197+
self.assertEqual(i, 4)
198+
199+
200+
if __name__ == "__main__":
201+
unittest.main()
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""Tests for global and nonlocal statements"""
2+
3+
import unittest
4+
5+
6+
class GlobalTest(unittest.TestCase):
7+
8+
def test_global_read(self):
9+
x = 42
10+
def f():
11+
return x
12+
self.assertEqual(f(), 42)
13+
14+
def test_global_write(self):
15+
def f():
16+
global _test_global_var
17+
_test_global_var = 99
18+
f()
19+
self.assertEqual(_test_global_var, 99)
20+
21+
def test_global_in_nested(self):
22+
result = []
23+
def outer():
24+
def inner():
25+
global _test_nested_global
26+
_test_nested_global = 42
27+
inner()
28+
outer()
29+
self.assertEqual(_test_nested_global, 42)
30+
31+
32+
class NonlocalTest(unittest.TestCase):
33+
34+
def test_nonlocal_read(self):
35+
def outer():
36+
x = 10
37+
def inner():
38+
return x
39+
return inner()
40+
self.assertEqual(outer(), 10)
41+
42+
def test_nonlocal_write(self):
43+
def outer():
44+
x = 10
45+
def inner():
46+
nonlocal x
47+
x = 20
48+
inner()
49+
return x
50+
self.assertEqual(outer(), 20)
51+
52+
def test_nonlocal_counter(self):
53+
def make_counter():
54+
count = 0
55+
def increment():
56+
nonlocal count
57+
count += 1
58+
return count
59+
return increment
60+
c = make_counter()
61+
self.assertEqual(c(), 1)
62+
self.assertEqual(c(), 2)
63+
self.assertEqual(c(), 3)
64+
65+
def test_nonlocal_multi_level(self):
66+
def outer():
67+
x = 0
68+
def middle():
69+
nonlocal x
70+
x += 1
71+
def inner():
72+
nonlocal x
73+
x += 10
74+
inner()
75+
middle()
76+
return x
77+
self.assertEqual(outer(), 11)
78+
79+
def test_nonlocal_multiple_vars(self):
80+
def outer():
81+
a = 1
82+
b = 2
83+
def inner():
84+
nonlocal a, b
85+
a, b = b, a
86+
inner()
87+
return a, b
88+
self.assertEqual(outer(), (2, 1))
89+
90+
91+
class ScopeTest(unittest.TestCase):
92+
93+
def test_local_shadows_global(self):
94+
x = 100
95+
def f():
96+
x = 200
97+
return x
98+
self.assertEqual(f(), 200)
99+
self.assertEqual(x, 100)
100+
101+
def test_enclosing_scope(self):
102+
def outer(x):
103+
def inner(y):
104+
return x + y
105+
return inner
106+
add5 = outer(5)
107+
self.assertEqual(add5(3), 8)
108+
109+
def test_class_scope(self):
110+
class C:
111+
x = 42
112+
def get_x(self):
113+
return self.x
114+
self.assertEqual(C().get_x(), 42)
115+
116+
def test_comprehension_scope(self):
117+
x = 99
118+
_ = [x for x in range(5)]
119+
self.assertEqual(x, 99) # comprehension doesn't leak
120+
121+
122+
if __name__ == "__main__":
123+
unittest.main()

0 commit comments

Comments
 (0)