Skip to content

Commit 2f76e12

Browse files
committed
Consider keyword-only arg 'default' in min/max.
1 parent 16580ad commit 2f76e12

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,32 +1281,38 @@ protected final BinaryComparisonNode createComparison() {
12811281
}
12821282

12831283
@Specialization(guards = "args.length == 0")
1284-
Object maxSequence(VirtualFrame frame, Object arg1, Object[] args, @SuppressWarnings("unused") PNone keywordArg,
1285-
@Cached("create()") GetIteratorNode getIterator,
1286-
@Cached("create()") GetNextNode next,
1284+
Object maxSequence(VirtualFrame frame, Object arg1, Object[] args, @SuppressWarnings("unused") PNone key, Object defaultVal,
1285+
@Cached GetIteratorNode getIterator,
1286+
@Cached GetNextNode next,
12871287
@Cached("createComparison()") BinaryComparisonNode compare,
12881288
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode,
1289-
@Cached("create()") IsBuiltinClassProfile errorProfile1,
1290-
@Cached("create()") IsBuiltinClassProfile errorProfile2) {
1291-
return minmaxSequenceWithKey(frame, arg1, args, null, getIterator, next, compare, castToBooleanNode, null, errorProfile1, errorProfile2);
1289+
@Cached IsBuiltinClassProfile errorProfile1,
1290+
@Cached IsBuiltinClassProfile errorProfile2,
1291+
@Shared("hasDefaultProfile") @Cached("createBinaryProfile()") ConditionProfile hasDefaultProfile) {
1292+
return minmaxSequenceWithKey(frame, arg1, args, null, defaultVal, getIterator, next, compare, castToBooleanNode, null, errorProfile1, errorProfile2, hasDefaultProfile);
12921293
}
12931294

12941295
@Specialization(guards = "args.length == 0")
1295-
Object minmaxSequenceWithKey(VirtualFrame frame, Object arg1, @SuppressWarnings("unused") Object[] args, Object keywordArg,
1296-
@Cached("create()") GetIteratorNode getIterator,
1297-
@Cached("create()") GetNextNode next,
1296+
Object minmaxSequenceWithKey(VirtualFrame frame, Object arg1, @SuppressWarnings("unused") Object[] args, Object keywordArg, Object defaultVal,
1297+
@Cached GetIteratorNode getIterator,
1298+
@Cached GetNextNode next,
12981299
@Cached("createComparison()") BinaryComparisonNode compare,
12991300
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode,
1300-
@Cached("create()") CallNode keyCall,
1301-
@Cached("create()") IsBuiltinClassProfile errorProfile1,
1302-
@Cached("create()") IsBuiltinClassProfile errorProfile2) {
1301+
@Cached CallNode keyCall,
1302+
@Cached IsBuiltinClassProfile errorProfile1,
1303+
@Cached IsBuiltinClassProfile errorProfile2,
1304+
@Shared("hasDefaultProfile") @Cached("createBinaryProfile()") ConditionProfile hasDefaultProfile) {
13031305
Object iterator = getIterator.executeWith(frame, arg1);
13041306
Object currentValue;
13051307
try {
13061308
currentValue = next.execute(frame, iterator);
13071309
} catch (PException e) {
13081310
e.expectStopIteration(errorProfile1);
1309-
throw raise(PythonErrorType.ValueError, ErrorMessages.ARG_IS_EMPTY_SEQ, this instanceof MaxNode ? "max" : "min");
1311+
if (hasDefaultProfile.profile(PGuards.isNoValue(defaultVal))) {
1312+
throw raise(PythonErrorType.ValueError, ErrorMessages.ARG_IS_EMPTY_SEQ, getName());
1313+
} else {
1314+
currentValue = defaultVal;
1315+
}
13101316
}
13111317
Object currentKey = applyKeyFunction(frame, keywordArg, keyCall, currentValue);
13121318
while (true) {
@@ -1338,20 +1344,30 @@ Object minmaxSequenceWithKey(VirtualFrame frame, Object arg1, @SuppressWarnings(
13381344
return currentValue;
13391345
}
13401346

1347+
private String getName() {
1348+
return this instanceof MaxNode ? "max" : "min";
1349+
}
1350+
13411351
@Specialization(guards = "args.length != 0")
1342-
Object minmaxBinary(VirtualFrame frame, Object arg1, Object[] args, @SuppressWarnings("unused") PNone keywordArg,
1352+
Object minmaxBinary(VirtualFrame frame, Object arg1, Object[] args, @SuppressWarnings("unused") PNone keywordArg, Object defaultVal,
13431353
@Cached("createComparison()") BinaryComparisonNode compare,
13441354
@Cached("createBinaryProfile()") ConditionProfile moreThanTwo,
1345-
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode) {
1346-
return minmaxBinaryWithKey(frame, arg1, args, null, compare, null, moreThanTwo, castToBooleanNode);
1355+
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode,
1356+
@Shared("hasDefaultProfile") @Cached("createBinaryProfile()") ConditionProfile hasDefaultProfile) {
1357+
return minmaxBinaryWithKey(frame, arg1, args, null, defaultVal, compare, null, moreThanTwo, castToBooleanNode, hasDefaultProfile);
13471358
}
13481359

13491360
@Specialization(guards = "args.length != 0")
1350-
Object minmaxBinaryWithKey(VirtualFrame frame, Object arg1, Object[] args, Object keywordArg,
1361+
Object minmaxBinaryWithKey(VirtualFrame frame, Object arg1, Object[] args, Object keywordArg, @SuppressWarnings("unused") Object defaultVal,
13511362
@Cached("createComparison()") BinaryComparisonNode compare,
13521363
@Cached CallNode keyCall,
13531364
@Cached("createBinaryProfile()") ConditionProfile moreThanTwo,
1354-
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode) {
1365+
@Shared("castToBooleanNode") @Cached("createIfTrueNode()") CoerceToBooleanNode castToBooleanNode,
1366+
@Shared("hasDefaultProfile") @Cached("createBinaryProfile()") ConditionProfile hasDefaultProfile) {
1367+
1368+
if (!hasDefaultProfile.profile(PGuards.isNoValue(defaultVal))) {
1369+
throw raise(PythonBuiltinClassType.TypeError, "Cannot specify a default for %s with multiple positional arguments", getName());
1370+
}
13551371
Object currentValue = arg1;
13561372
Object currentKey = applyKeyFunction(frame, keywordArg, keyCall, currentValue);
13571373
Object nextValue = args[0];
@@ -1399,15 +1415,15 @@ private static Object applyKeyFunction(VirtualFrame frame, Object keywordArg, Ca
13991415

14001416
// max(iterable, *[, key])
14011417
// max(arg1, arg2, *args[, key])
1402-
@Builtin(name = MAX, minNumOfPositionalArgs = 1, takesVarArgs = true, keywordOnlyNames = {"key"})
1418+
@Builtin(name = MAX, minNumOfPositionalArgs = 1, takesVarArgs = true, keywordOnlyNames = {"key", "default"})
14031419
@GenerateNodeFactory
14041420
public abstract static class MaxNode extends MinMaxNode {
14051421

14061422
}
14071423

14081424
// min(iterable, *[, key])
14091425
// min(arg1, arg2, *args[, key])
1410-
@Builtin(name = MIN, minNumOfPositionalArgs = 1, takesVarArgs = true, keywordOnlyNames = {"key"})
1426+
@Builtin(name = MIN, minNumOfPositionalArgs = 1, takesVarArgs = true, keywordOnlyNames = {"key", "default"})
14111427
@GenerateNodeFactory
14121428
public abstract static class MinNode extends MinMaxNode {
14131429

0 commit comments

Comments
 (0)