@@ -676,7 +676,7 @@ def complex_func(a, b=1, *args, c, d=2, **kwargs):
676676 (1 , 1 , (), 3 , 2 , {}),
677677 (1 , 2 , (3 , 4 ), 5 , 6 , {"x" : 7 }),
678678 (1 , 2 , (), 3 , 4 , {"x" : 5 , "y" : 6 }),
679- "missing required keyword-only argument 'c'" ,
679+ "complex_func() missing 1 required keyword-only argument: 'c'" ,
680680 ]
681681
682682 # Test function with nonlocal and closure
@@ -1081,3 +1081,295 @@ class Score:
10811081 tree = parser .parse (code )
10821082 result = interpreter .execute (tree )
10831083 assert result == [85 , "Value must be >= 0" , "Value must be <= 100" ]
1084+
1085+
1086+ def test_function_call_edge_cases ():
1087+ """Test edge cases in function calls."""
1088+ parser = ExpressionsParser ()
1089+ interpreter = ExpressionsInterpreter ()
1090+
1091+ # Test function call with invalid arguments
1092+ code = """
1093+ def func(a, b, *, c):
1094+ return a + b + c
1095+
1096+ results = []
1097+ try:
1098+ func(1, 2, 3) # Positional argument after keyword-only argument
1099+ except TypeError as e:
1100+ results.append(str(e))
1101+
1102+ try:
1103+ func(1, b=2) # Missing required keyword-only argument
1104+ except TypeError as e:
1105+ results.append(str(e))
1106+
1107+ try:
1108+ func(1, 2, d=3) # Unknown keyword argument
1109+ except TypeError as e:
1110+ results.append(str(e))
1111+
1112+ results
1113+ """
1114+ tree = parser .parse (code )
1115+ result = interpreter .execute (tree )
1116+ assert result == [
1117+ "func() takes 2 positional arguments but 3 were given" ,
1118+ "func() missing 1 required keyword-only argument: 'c'" ,
1119+ "func() got an unexpected keyword argument 'd'" ,
1120+ ]
1121+
1122+ # Test method call with invalid arguments
1123+ code = """
1124+ class Test:
1125+ def method(self, a, b=2):
1126+ return a + b
1127+
1128+ @classmethod
1129+ def class_method(cls, x):
1130+ return x * 2
1131+
1132+ @staticmethod
1133+ def static_method(y):
1134+ return y + 1
1135+
1136+ obj = Test()
1137+ results = []
1138+
1139+ # Test instance method
1140+ results.append(obj.method(1))
1141+ results.append(obj.method(1, 3))
1142+
1143+ # Test classmethod
1144+ results.append(Test.class_method(5))
1145+ results.append(obj.class_method(5))
1146+
1147+ # Test staticmethod
1148+ results.append(Test.static_method(10))
1149+ results.append(obj.static_method(10))
1150+
1151+ try:
1152+ obj.method() # Missing required argument
1153+ except TypeError as e:
1154+ results.append(str(e))
1155+
1156+ try:
1157+ obj.method(1, 2, 3) # Too many arguments
1158+ except TypeError as e:
1159+ results.append(str(e))
1160+
1161+ results
1162+ """
1163+ tree = parser .parse (code )
1164+ result = interpreter .execute (tree )
1165+ assert result == [
1166+ 3 ,
1167+ 4 ,
1168+ 10 ,
1169+ 10 ,
1170+ 11 ,
1171+ 11 ,
1172+ "method() missing 1 required positional argument: 'a'" ,
1173+ "method() takes from 2 to 3 positional arguments but 4 were given" ,
1174+ ]
1175+
1176+
1177+ def test_generator_advanced_features ():
1178+ """Test advanced generator features."""
1179+ parser = ExpressionsParser ()
1180+ interpreter = ExpressionsInterpreter ()
1181+
1182+ # Test generator with try/finally
1183+ code = """
1184+ def gen():
1185+ yield 1
1186+ yield 2
1187+
1188+ results = []
1189+ g = gen()
1190+ results.append(next(g))
1191+ results.append(next(g))
1192+ try:
1193+ next(g)
1194+ except StopIteration:
1195+ results.append('stopped')
1196+ results
1197+ """
1198+ tree = parser .parse (code )
1199+ result = interpreter .execute (tree )
1200+ assert result == [1 , 2 , "stopped" ]
1201+
1202+ # Test generator with throw
1203+ code = """
1204+ def gen_with_throw():
1205+ yield 1
1206+ yield 2
1207+ yield 3
1208+ yield 'end'
1209+
1210+ results = []
1211+ g = gen_with_throw()
1212+ results.append(next(g))
1213+ results.append(next(g))
1214+ try:
1215+ g.throw(ValueError)
1216+ except ValueError:
1217+ results.append('caught')
1218+ except StopIteration:
1219+ results.append('stopped')
1220+ results
1221+ """
1222+ tree = parser .parse (code )
1223+ result = interpreter .execute (tree )
1224+ assert result == [1 , 2 , "caught" ]
1225+
1226+
1227+ def test_comprehension_advanced_features ():
1228+ """Test advanced comprehension features."""
1229+ parser = ExpressionsParser ()
1230+ interpreter = ExpressionsInterpreter ()
1231+
1232+ # Test nested comprehensions with complex conditions
1233+ code = """
1234+ def get_data():
1235+ return [[j for j in range(i + 1)] for i in range(3)]
1236+
1237+ results = []
1238+ # List comprehension
1239+ results.append([sum(row) for row in get_data()])
1240+
1241+ # Set comprehension with tuple unpacking
1242+ points = [(1, 2), (3, 4), (1, 2), (5, 6)]
1243+ results.append({(y, x) for x, y in points})
1244+
1245+ # Dict comprehension with complex key generation
1246+ words = ['hello', 'world', 'python']
1247+ results.append({word: {c: word.count(c) for c in set(word)}
1248+ for word in words if len(word) > 4})
1249+
1250+ results
1251+ """
1252+ tree = parser .parse (code )
1253+ result = interpreter .execute (tree )
1254+ assert result == [
1255+ [0 , 1 , 3 ], # Sum of each row
1256+ {(2 , 1 ), (4 , 3 ), (6 , 5 )}, # Swapped coordinates
1257+ {
1258+ "hello" : {"h" : 1 , "o" : 1 , "e" : 1 , "l" : 2 },
1259+ "world" : {"o" : 1 , "l" : 1 , "r" : 1 , "d" : 1 , "w" : 1 },
1260+ "python" : {"o" : 1 , "t" : 1 , "p" : 1 , "y" : 1 , "n" : 1 , "h" : 1 },
1261+ },
1262+ ]
1263+
1264+ # Test comprehension with error handling
1265+ code = """
1266+ def problematic_data():
1267+ yield 1
1268+ yield 'not a number'
1269+ yield 3
1270+
1271+ results = []
1272+ try:
1273+ results.append([x * 2 for x in problematic_data()])
1274+ except TypeError as e:
1275+ results.append(str(e))
1276+
1277+ # Generator expression with error
1278+ def gen_expr():
1279+ return (x * 2 for x in problematic_data())
1280+
1281+ g = gen_expr()
1282+ results.append(next(g))
1283+ try:
1284+ next(g)
1285+ except TypeError as e:
1286+ results.append(str(e))
1287+
1288+ results
1289+ """
1290+ tree = parser .parse (code )
1291+ result = interpreter .execute (tree )
1292+ assert result == [[2 , "not a numbernot a number" , 6 ], 2 ]
1293+
1294+
1295+ def test_match_pattern_advanced ():
1296+ """Test advanced pattern matching features."""
1297+ parser = ExpressionsParser ()
1298+ interpreter = ExpressionsInterpreter ()
1299+
1300+ # Test match with custom class patterns
1301+ code = """
1302+ class Point:
1303+ def __init__(self, x, y):
1304+ self.x = x
1305+ self.y = y
1306+ __match_args__ = ('x', 'y')
1307+
1308+ class Line:
1309+ def __init__(self, start, end):
1310+ self.start = start
1311+ self.end = end
1312+ __match_args__ = ('start', 'end')
1313+
1314+ def classify(shape):
1315+ match shape:
1316+ case Point(0, y):
1317+ return f"Point on y-axis at y={y}"
1318+ case Point(x, 0):
1319+ return f"Point on x-axis at x={x}"
1320+ case Point(x, y) if x == y:
1321+ return f"Point on diagonal at {x}"
1322+ case Line(Point(x1, y1), Point(x2, y2)) if x1 == x2:
1323+ return f"Vertical line at x={x1}"
1324+ case Line(Point(x1, y1), Point(x2, y2)) if y1 == y2:
1325+ return f"Horizontal line at y={y1}"
1326+ case _:
1327+ return "Other shape"
1328+
1329+ results = []
1330+ results.append(classify(Point(0, 5)))
1331+ results.append(classify(Point(3, 0)))
1332+ results.append(classify(Point(4, 4)))
1333+ results.append(classify(Line(Point(2, 1), Point(2, 5))))
1334+ results.append(classify(Line(Point(1, 3), Point(5, 3))))
1335+ results.append(classify(Line(Point(1, 1), Point(2, 2))))
1336+ results
1337+ """
1338+ tree = parser .parse (code )
1339+ result = interpreter .execute (tree )
1340+ assert result == [
1341+ "Point on y-axis at y=5" ,
1342+ "Point on x-axis at x=3" ,
1343+ "Point on diagonal at 4" ,
1344+ "Vertical line at x=2" ,
1345+ "Horizontal line at y=3" ,
1346+ "Other shape" ,
1347+ ]
1348+
1349+
1350+ def test_async_function_advanced ():
1351+ """Test advanced async function features."""
1352+ parser = ExpressionsParser ()
1353+ interpreter = ExpressionsInterpreter ()
1354+
1355+ # Test async function with error handling
1356+ code = """
1357+ async def the_answer():
1358+ return 42
1359+
1360+ async def async_with_error():
1361+ try:
1362+ await the_answer()
1363+ raise ValueError('test error')
1364+ except ValueError as e:
1365+ return str(e)
1366+
1367+ async def run_async():
1368+ return await async_with_error()
1369+
1370+ result = await run_async()
1371+ result
1372+ """
1373+ tree = parser .parse (code )
1374+ result = interpreter .execute (tree )
1375+ assert result == "test error"
0 commit comments