Skip to content

Commit 28ff34b

Browse files
jgarzikclaude
andcommitted
Import test_decorators_extra, test_walrus, test_match, test_datastructures
New tests: - test_decorators_extra.py: 8 tests — function/class/method decorators, stacked, with args, staticmethod, classmethod, property - test_walrus.py: 5 tests — assignment expressions in if/while/listcomp - test_match.py: 8 tests — match/case with literals, strings, capture, or-pattern, guard, tuple pattern, None/True/False patterns - test_datastructures.py: 14 tests — nested structures, frequency count, groupby, sorting with key/reverse, stable sort Total CPython test suites: 60 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c2dee48 commit 28ff34b

5 files changed

Lines changed: 365 additions & 0 deletions

File tree

Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ gen-cpython-tests:
159159
@$(PYTHON) -m py_compile tests/cpython/test_slice_ops.py
160160
@$(PYTHON) -m py_compile tests/cpython/test_numeric.py
161161
@$(PYTHON) -m py_compile tests/cpython/test_comprehensions.py
162+
@$(PYTHON) -m py_compile tests/cpython/test_decorators_extra.py
163+
@$(PYTHON) -m py_compile tests/cpython/test_walrus.py
164+
@$(PYTHON) -m py_compile tests/cpython/test_match.py
165+
@$(PYTHON) -m py_compile tests/cpython/test_datastructures.py
162166
@echo "Done."
163167

164168
check-cpython: $(TARGET) gen-cpython-tests
@@ -274,3 +278,11 @@ check-cpython: $(TARGET) gen-cpython-tests
274278
@./apython tests/cpython/__pycache__/test_numeric.cpython-312.pyc
275279
@echo "Running CPython test_comprehensions.py..."
276280
@./apython tests/cpython/__pycache__/test_comprehensions.cpython-312.pyc
281+
@echo "Running CPython test_decorators_extra.py..."
282+
@./apython tests/cpython/__pycache__/test_decorators_extra.cpython-312.pyc
283+
@echo "Running CPython test_walrus.py..."
284+
@./apython tests/cpython/__pycache__/test_walrus.cpython-312.pyc
285+
@echo "Running CPython test_match.py..."
286+
@./apython tests/cpython/__pycache__/test_match.cpython-312.pyc
287+
@echo "Running CPython test_datastructures.py..."
288+
@./apython tests/cpython/__pycache__/test_datastructures.cpython-312.pyc
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
"""Tests for data structure operations — mixed-type scenarios"""
2+
3+
import unittest
4+
5+
6+
class NestedStructTest(unittest.TestCase):
7+
8+
def test_list_of_dicts(self):
9+
data = [{"name": "a", "val": 1}, {"name": "b", "val": 2}]
10+
self.assertEqual(data[0]["name"], "a")
11+
self.assertEqual(data[1]["val"], 2)
12+
13+
def test_dict_of_lists(self):
14+
d = {"evens": [0, 2, 4], "odds": [1, 3, 5]}
15+
self.assertEqual(d["evens"][1], 2)
16+
self.assertEqual(d["odds"][2], 5)
17+
18+
def test_nested_list(self):
19+
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
20+
flat = [x for row in matrix for x in row]
21+
self.assertEqual(flat, [1, 2, 3, 4, 5, 6, 7, 8, 9])
22+
23+
def test_list_of_tuples(self):
24+
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
25+
keys = [k for k, v in pairs]
26+
vals = [v for k, v in pairs]
27+
self.assertEqual(keys, [1, 2, 3])
28+
self.assertEqual(vals, ['a', 'b', 'c'])
29+
30+
def test_dict_from_zip(self):
31+
keys = ['a', 'b', 'c']
32+
vals = [1, 2, 3]
33+
d = {}
34+
for k, v in zip(keys, vals):
35+
d[k] = v
36+
self.assertEqual(d['b'], 2)
37+
38+
def test_set_from_list(self):
39+
data = [1, 2, 2, 3, 3, 3]
40+
unique = sorted(list(set(data)))
41+
self.assertEqual(unique, [1, 2, 3])
42+
43+
def test_stack(self):
44+
stack = []
45+
stack.append(1)
46+
stack.append(2)
47+
stack.append(3)
48+
self.assertEqual(stack.pop(), 3)
49+
self.assertEqual(stack.pop(), 2)
50+
self.assertEqual(len(stack), 1)
51+
52+
def test_queue_via_list(self):
53+
q = []
54+
q.append("first")
55+
q.append("second")
56+
q.append("third")
57+
self.assertEqual(q.pop(0), "first")
58+
self.assertEqual(q.pop(0), "second")
59+
60+
def test_frequency_count(self):
61+
text = "abracadabra"
62+
freq = {}
63+
for ch in text:
64+
freq[ch] = freq.get(ch, 0) + 1
65+
self.assertEqual(freq['a'], 5)
66+
self.assertEqual(freq['b'], 2)
67+
68+
def test_groupby_manual(self):
69+
data = [("a", 1), ("b", 2), ("a", 3), ("b", 4)]
70+
groups = {}
71+
for key, val in data:
72+
if key not in groups:
73+
groups[key] = []
74+
groups[key].append(val)
75+
self.assertEqual(groups["a"], [1, 3])
76+
self.assertEqual(groups["b"], [2, 4])
77+
78+
79+
class SortingTest(unittest.TestCase):
80+
81+
def test_sort_key(self):
82+
data = ["banana", "apple", "cherry"]
83+
data.sort(key=len)
84+
self.assertEqual(data, ["apple", "banana", "cherry"])
85+
86+
def test_sorted_key(self):
87+
data = [(3, "c"), (1, "a"), (2, "b")]
88+
result = sorted(data, key=lambda x: x[0])
89+
self.assertEqual(result, [(1, "a"), (2, "b"), (3, "c")])
90+
91+
def test_reverse_sort(self):
92+
data = [3, 1, 4, 1, 5]
93+
self.assertEqual(sorted(data, reverse=True), [5, 4, 3, 1, 1])
94+
95+
def test_stable_sort(self):
96+
data = [(1, 'b'), (2, 'a'), (1, 'a'), (2, 'b')]
97+
result = sorted(data, key=lambda x: x[0])
98+
self.assertEqual(result[0], (1, 'b'))
99+
self.assertEqual(result[1], (1, 'a'))
100+
101+
102+
if __name__ == "__main__":
103+
unittest.main()
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""Extra decorator tests"""
2+
3+
import unittest
4+
5+
6+
class DecoratorTest(unittest.TestCase):
7+
8+
def test_function_decorator(self):
9+
def double(f):
10+
def wrapper(*args):
11+
return f(*args) * 2
12+
return wrapper
13+
@double
14+
def add(a, b):
15+
return a + b
16+
self.assertEqual(add(3, 4), 14)
17+
18+
def test_stacked_decorators(self):
19+
def add_one(f):
20+
def w(*a):
21+
return f(*a) + 1
22+
return w
23+
def times_two(f):
24+
def w(*a):
25+
return f(*a) * 2
26+
return w
27+
@add_one
28+
@times_two
29+
def val():
30+
return 5
31+
# times_two applied first: 5*2=10, then add_one: 10+1=11
32+
self.assertEqual(val(), 11)
33+
34+
def test_decorator_with_args(self):
35+
def repeat(n):
36+
def decorator(f):
37+
def wrapper(*args):
38+
return [f(*args) for _ in range(n)]
39+
return wrapper
40+
return decorator
41+
@repeat(3)
42+
def greet():
43+
return "hi"
44+
self.assertEqual(greet(), ["hi", "hi", "hi"])
45+
46+
def test_class_decorator(self):
47+
def add_method(cls):
48+
cls.extra = lambda self: 42
49+
return cls
50+
@add_method
51+
class C:
52+
pass
53+
self.assertEqual(C().extra(), 42)
54+
55+
def test_method_decorator(self):
56+
def log(f):
57+
def wrapper(self, *args):
58+
self.calls.append(f.__name__)
59+
return f(self, *args)
60+
return wrapper
61+
class C:
62+
def __init__(self):
63+
self.calls = []
64+
@log
65+
def do_thing(self):
66+
return "done"
67+
obj = C()
68+
obj.do_thing()
69+
self.assertEqual(obj.calls, ["do_thing"])
70+
71+
def test_staticmethod(self):
72+
class C:
73+
@staticmethod
74+
def f(x):
75+
return x + 1
76+
self.assertEqual(C.f(5), 6)
77+
self.assertEqual(C().f(5), 6)
78+
79+
def test_classmethod(self):
80+
class C:
81+
val = 10
82+
@classmethod
83+
def get_val(cls):
84+
return cls.val
85+
self.assertEqual(C.get_val(), 10)
86+
87+
def test_property_decorator(self):
88+
class C:
89+
def __init__(self, x):
90+
self._x = x
91+
@property
92+
def x(self):
93+
return self._x
94+
@x.setter
95+
def x(self, val):
96+
self._x = val
97+
obj = C(10)
98+
self.assertEqual(obj.x, 10)
99+
obj.x = 20
100+
self.assertEqual(obj.x, 20)
101+
102+
103+
if __name__ == "__main__":
104+
unittest.main()

tests/cpython/test_match.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"""Tests for match statement (PEP 634)"""
2+
3+
import unittest
4+
5+
6+
class MatchBasicTest(unittest.TestCase):
7+
8+
def test_literal(self):
9+
def f(x):
10+
match x:
11+
case 1:
12+
return "one"
13+
case 2:
14+
return "two"
15+
case _:
16+
return "other"
17+
self.assertEqual(f(1), "one")
18+
self.assertEqual(f(2), "two")
19+
self.assertEqual(f(99), "other")
20+
21+
def test_string_literal(self):
22+
def f(cmd):
23+
match cmd:
24+
case "start":
25+
return 1
26+
case "stop":
27+
return 0
28+
case _:
29+
return -1
30+
self.assertEqual(f("start"), 1)
31+
self.assertEqual(f("stop"), 0)
32+
self.assertEqual(f("other"), -1)
33+
34+
def test_capture(self):
35+
def f(x):
36+
match x:
37+
case [a, b]:
38+
return a + b
39+
case _:
40+
return -1
41+
self.assertEqual(f([10, 20]), 30)
42+
43+
def test_or_pattern(self):
44+
def f(x):
45+
match x:
46+
case 1 | 2 | 3:
47+
return "small"
48+
case _:
49+
return "big"
50+
self.assertEqual(f(1), "small")
51+
self.assertEqual(f(2), "small")
52+
self.assertEqual(f(5), "big")
53+
54+
def test_guard(self):
55+
def f(x):
56+
match x:
57+
case n if n > 0:
58+
return "positive"
59+
case n if n < 0:
60+
return "negative"
61+
case _:
62+
return "zero"
63+
self.assertEqual(f(5), "positive")
64+
self.assertEqual(f(-3), "negative")
65+
self.assertEqual(f(0), "zero")
66+
67+
def test_tuple_pattern(self):
68+
def f(point):
69+
match point:
70+
case (0, 0):
71+
return "origin"
72+
case (x, 0):
73+
return "x-axis"
74+
case (0, y):
75+
return "y-axis"
76+
case (x, y):
77+
return "other"
78+
self.assertEqual(f((0, 0)), "origin")
79+
self.assertEqual(f((5, 0)), "x-axis")
80+
self.assertEqual(f((0, 3)), "y-axis")
81+
self.assertEqual(f((1, 2)), "other")
82+
83+
def test_none_pattern(self):
84+
def f(x):
85+
match x:
86+
case None:
87+
return "none"
88+
case _:
89+
return "something"
90+
self.assertEqual(f(None), "none")
91+
self.assertEqual(f(42), "something")
92+
93+
def test_bool_pattern(self):
94+
def f(x):
95+
match x:
96+
case True:
97+
return "true"
98+
case False:
99+
return "false"
100+
case _:
101+
return "other"
102+
self.assertEqual(f(True), "true")
103+
self.assertEqual(f(False), "false")
104+
105+
106+
if __name__ == "__main__":
107+
unittest.main()

tests/cpython/test_walrus.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""Tests for walrus operator (:=) — assignment expressions"""
2+
3+
import unittest
4+
5+
6+
class WalrusTest(unittest.TestCase):
7+
8+
def test_basic(self):
9+
if (n := 10) > 5:
10+
result = n
11+
self.assertEqual(result, 10)
12+
13+
def test_in_while(self):
14+
data = [1, 2, 3, 0, 4, 5]
15+
idx = 0
16+
result = []
17+
while (val := data[idx]) != 0:
18+
result.append(val)
19+
idx += 1
20+
self.assertEqual(result, [1, 2, 3])
21+
22+
def test_in_list_comp(self):
23+
results = [y for x in range(5) if (y := x * x) > 5]
24+
self.assertEqual(results, [9, 16])
25+
26+
def test_in_expression(self):
27+
x = [y := 42]
28+
self.assertEqual(x, [42])
29+
self.assertEqual(y, 42)
30+
31+
def test_nested(self):
32+
a = (b := (c := 5) + 1) + 2
33+
self.assertEqual(c, 5)
34+
self.assertEqual(b, 6)
35+
self.assertEqual(a, 8)
36+
37+
38+
if __name__ == "__main__":
39+
unittest.main()

0 commit comments

Comments
 (0)