Skip to content

Commit 5dcdc23

Browse files
committed
[GR-27170] Fixed handling of positional arguments
PullRequest: graalpython/1387
2 parents 83a5309 + 5da4f2b commit 5dcdc23

File tree

6 files changed

+33
-19
lines changed

6 files changed

+33
-19
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
import com.oracle.graal.python.nodes.call.CallNode;
6666
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6767
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
68-
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
68+
import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
6969
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
7070
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
7171
import com.oracle.graal.python.nodes.statement.RaiseNode;
@@ -241,7 +241,7 @@ private void raiseObject(Object exceptionObject, String message) {
241241
@Builtin(name = "b2a_base64", minNumOfPositionalArgs = 1, numOfPositionalOnlyArgs = 1, parameterNames = {"data"}, keywordOnlyNames = {"newline"})
242242
@ArgumentClinic(name = "newline", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "1", useDefaultForNone = true)
243243
@GenerateNodeFactory
244-
abstract static class B2aBase64Node extends PythonBinaryClinicBuiltinNode {
244+
abstract static class B2aBase64Node extends PythonClinicBuiltinNode {
245245
@TruffleBoundary
246246
private static byte[] b2a(byte[] data, int newline) {
247247
String encode = Base64.encode(data);

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
import com.oracle.graal.python.nodes.ErrorMessages;
1717
import com.oracle.graal.python.nodes.PGuards;
1818
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
19+
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
1920
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
20-
import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode;
2121
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
2222
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
2323
import com.oracle.graal.python.nodes.util.CoerceToComplexNode;
@@ -993,11 +993,11 @@ static TanhNode create() {
993993
}
994994
}
995995

996-
@Builtin(name = "isclose", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2, keywordOnlyNames = {"rel_tol", "abs_tol"})
996+
@Builtin(name = "isclose", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 2, varArgsMarker = true, keywordOnlyNames = {"rel_tol", "abs_tol"})
997997
@TypeSystemReference(PythonArithmeticTypes.class)
998998
@ImportStatic(MathGuards.class)
999999
@GenerateNodeFactory
1000-
abstract static class IsCloseNode extends PythonQuaternaryBuiltinNode {
1000+
abstract static class IsCloseNode extends PythonBuiltinNode {
10011001

10021002
private static final double DEFAULT_REL_TOL = 1e-09;
10031003
private static final double DEFAULT_ABS_TOL = 0;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1868,7 +1868,7 @@ protected static GetTerminalSizeNode create() {
18681868
@Builtin(name = "readlink", minNumOfPositionalArgs = 1, parameterNames = {"path"}, varArgsMarker = true, keywordOnlyNames = {"dirFd"}, doc = "readlink(path, *, dir_fd=None) -> path\n" +
18691869
"\nReturn a string representing the path to which the symbolic link points.\n")
18701870
@GenerateNodeFactory
1871-
abstract static class ReadlinkNode extends PythonBinaryBuiltinNode {
1871+
abstract static class ReadlinkNode extends PythonBuiltinNode {
18721872
@Specialization(limit = "1")
18731873
String readlink(VirtualFrame frame, Object str, @SuppressWarnings("unused") PNone none,
18741874
@CachedLibrary("str") PythonObjectLibrary lib) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import com.oracle.graal.python.nodes.ErrorMessages;
5555
import com.oracle.graal.python.nodes.SpecialMethodNames;
5656
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
57+
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
5758
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5859
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
5960
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -118,7 +119,7 @@ boolean test(PDirEntry self) {
118119

119120
@Builtin(name = "is_dir", minNumOfPositionalArgs = 1, keywordOnlyNames = {"follow_symlinks"}, needsFrame = true)
120121
@GenerateNodeFactory
121-
abstract static class IsDirNode extends PythonBinaryBuiltinNode {
122+
abstract static class IsDirNode extends PythonBuiltinNode {
122123
@Specialization
123124
boolean testBool(PDirEntry self, boolean followSymlinks) {
124125
return self.getFile().isDirectory(getLinkOption(followSymlinks));

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/CreateArgumentsNode.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ private static Object[] createAndCheckArguments(PythonObject callable, Object[]
329329

330330
if (too_many_args) {
331331
// the node acts as a profile
332-
throw handleTooManyArguments(scope_w, callable, signature, co_argcount, co_kwonlyargcount, defaults.length, avail, methodcall, handleTooMany);
332+
throw handleTooManyArguments(scope_w, callable, signature, co_argcount, co_kwonlyargcount, defaults.length, avail, methodcall, handleTooMany, self instanceof PythonModule ? 1 : 0);
333333
}
334334

335335
boolean more_filling = input_argcount < co_argcount + co_kwonlyargcount;
@@ -355,8 +355,8 @@ private static void applyKeywords(Object callable, Signature signature, Object[]
355355
}
356356

357357
private static PException handleTooManyArguments(Object[] scope_w, Object callable, Signature signature, int co_argcount, int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall,
358-
HandleTooManyArgumentsNode node) {
359-
return node.execute(scope_w, callable, signature, co_argcount, co_kwonlyargcount, ndefaults, avail, methodcall);
358+
HandleTooManyArgumentsNode node, int adjustCount) {
359+
return node.execute(scope_w, callable, signature, co_argcount, co_kwonlyargcount, ndefaults, avail, methodcall, adjustCount);
360360
}
361361

362362
private static void fillDefaults(Object callable, Signature signature, Object[] scope_w, Object[] defaults, int input_argcount, int co_argcount, FillDefaultsNode node) {
@@ -372,12 +372,13 @@ private static void fillKwDefaults(Object callable, Object[] scope_w, Signature
372372
@GenerateUncached
373373
protected abstract static class HandleTooManyArgumentsNode extends PNodeWithContext {
374374

375-
public abstract PException execute(Object[] scope_w, Object callable, Signature signature, int co_argcount, int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall);
375+
public abstract PException execute(Object[] scope_w, Object callable, Signature signature, int co_argcount, int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall,
376+
int adjustCount);
376377

377378
@Specialization(guards = {"co_kwonlyargcount == cachedKwOnlyArgCount"})
378379
@ExplodeLoop
379380
PException doCached(Object[] scope_w, Object callable, Signature signature, int co_argcount, @SuppressWarnings("unused") int co_kwonlyargcount, int ndefaults, int avail,
380-
boolean methodcall,
381+
boolean methodcall, int adjustCount,
381382
@Cached PRaiseNode raise,
382383
@Cached("co_kwonlyargcount") int cachedKwOnlyArgCount) {
383384
int kwonly_given = 0;
@@ -386,23 +387,21 @@ PException doCached(Object[] scope_w, Object callable, Signature signature, int
386387
kwonly_given += 1;
387388
}
388389
}
389-
390390
boolean forgotSelf = methodcall && avail + 1 == co_argcount && (signature.getParameterIds().length == 0 || !signature.getParameterIds()[0].equals("self"));
391-
throw raiseTooManyArguments(callable, co_argcount, ndefaults, avail, forgotSelf, kwonly_given, raise);
391+
throw raiseTooManyArguments(callable, co_argcount - adjustCount, ndefaults, avail - adjustCount, forgotSelf, kwonly_given, raise);
392392
}
393393

394394
@Specialization(replaces = "doCached")
395-
PException doUncached(Object[] scope_w, Object callable, Signature signature, int co_argcount, int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall,
395+
PException doUncached(Object[] scope_w, Object callable, Signature signature, int co_argcount, int co_kwonlyargcount, int ndefaults, int avail, boolean methodcall, int adjustCount,
396396
@Cached PRaiseNode raise) {
397397
int kwonly_given = 0;
398398
for (int i = 0; i < co_kwonlyargcount; i++) {
399399
if (PArguments.getArgument(scope_w, co_argcount + i) != null) {
400400
kwonly_given += 1;
401401
}
402402
}
403-
404403
boolean forgotSelf = methodcall && avail + 1 == co_argcount && (signature.getParameterIds().length == 0 || !signature.getParameterIds()[0].equals("self"));
405-
throw raiseTooManyArguments(callable, co_argcount, ndefaults, avail, forgotSelf, kwonly_given, raise);
404+
throw raiseTooManyArguments(callable, co_argcount - adjustCount, ndefaults, avail - adjustCount, forgotSelf, kwonly_given, raise);
406405
}
407406

408407
private static PException raiseTooManyArguments(Object callable, int co_argcount, int ndefaults, int avail, boolean forgotSelf, int kwonly_given, PRaiseNode raise) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/BuiltinFunctionRootNode.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,25 @@ private static Signature createSignature(NodeFactory<? extends PythonBuiltinBase
179179
}
180180
}
181181
}
182-
183-
return new Signature(builtin.numOfPositionalOnlyArgs(), builtin.takesVarKeywordArgs(), (builtin.takesVarArgs() || builtin.varArgsMarker()) ? parameterNames.length : -1,
182+
assert canUseSpecialBuiltinNode(builtin) || !usesSpecialBuiltinNode(factory.getNodeClass()) : factory.getNodeClass().getName() +
183+
" must not use PythonUnary/Binary/Ternary/QuaternaryBultinNode";
184+
return new Signature(builtin.numOfPositionalOnlyArgs(), builtin.takesVarKeywordArgs(), builtin.takesVarArgs() ? parameterNames.length : -1,
184185
builtin.varArgsMarker(), parameterNames, builtin.keywordOnlyNames());
185186
}
186187

188+
// Nodes for specific number of args n=1..4 (PythonUnaryBultinNode..PythonQuaternaryBultinNode)
189+
// can only be used by builtins with up to n positional arguments (without varargs/kwargs).
190+
// (Note that this does not apply to PythonVarargsBuiltinNode which can be used with
191+
// varargs/kwargs builtins.)
192+
private static boolean canUseSpecialBuiltinNode(Builtin builtin) {
193+
return !builtin.takesVarArgs() && !builtin.takesVarKeywordArgs() && !builtin.varArgsMarker() && builtin.keywordOnlyNames().length == 0;
194+
}
195+
196+
private static boolean usesSpecialBuiltinNode(Class<? extends PythonBuiltinBaseNode> clazz) {
197+
return PythonUnaryBuiltinNode.class.isAssignableFrom(clazz) || PythonBinaryBuiltinNode.class.isAssignableFrom(clazz) || PythonTernaryBuiltinNode.class.isAssignableFrom(clazz) ||
198+
PythonQuaternaryBuiltinNode.class.isAssignableFrom(clazz);
199+
}
200+
187201
/**
188202
* Must return argument reads compatible with
189203
* {@link #createSignature(NodeFactory, Builtin, boolean)}

0 commit comments

Comments
 (0)