Skip to content

Commit f9712cd

Browse files
committed
support follow_symlinks keyword arg in is_dir
1 parent c8a7e1d commit f9712cd

File tree

1 file changed

+29
-4
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix

1 file changed

+29
-4
lines changed

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

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.posix;
4242

43+
import java.nio.file.LinkOption;
4344
import java.util.List;
4445

4546
import com.oracle.graal.python.builtins.Builtin;
@@ -51,7 +52,9 @@
5152
import com.oracle.graal.python.nodes.SpecialMethodNames;
5253
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
5354
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
55+
import com.oracle.graal.python.nodes.expression.CastToBooleanNode;
5456
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
57+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5558
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
5659
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5760
import com.oracle.truffle.api.dsl.Cached;
@@ -62,6 +65,9 @@
6265
@CoreFunctions(extendClasses = PythonBuiltinClassType.PDirEntry)
6366
public class DirEntryBuiltins extends PythonBuiltins {
6467

68+
private static final LinkOption[] NOFOLLOW_LINKS_OPTIONS = new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
69+
private static final LinkOption[] NO_LINK_OPTIONS = new LinkOption[0];
70+
6571
@Override
6672
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
6773
return DirEntryBuiltinsFactory.getFactories();
@@ -95,6 +101,10 @@ PNone inode(@SuppressWarnings("unused") PDirEntry self) {
95101
}
96102
}
97103

104+
private static LinkOption[] getLinkOption(boolean followSymlinks) {
105+
return followSymlinks ? NO_LINK_OPTIONS : NOFOLLOW_LINKS_OPTIONS;
106+
}
107+
98108
@Builtin(name = "is_symlink", minNumOfPositionalArgs = 1)
99109
@GenerateNodeFactory
100110
abstract static class IsSymNode extends PythonUnaryBuiltinNode {
@@ -104,12 +114,27 @@ boolean test(PDirEntry self) {
104114
}
105115
}
106116

107-
@Builtin(name = "is_dir", minNumOfPositionalArgs = 1)
117+
@Builtin(name = "is_dir", minNumOfPositionalArgs = 1, keywordOnlyNames = {"follow_symlinks"})
108118
@GenerateNodeFactory
109-
abstract static class IsDirNode extends PythonUnaryBuiltinNode {
119+
abstract static class IsDirNode extends PythonBinaryBuiltinNode {
110120
@Specialization
111-
boolean test(PDirEntry self) {
112-
return self.getFile().isDirectory();
121+
boolean testBool(PDirEntry self, boolean followSymlinks) {
122+
return self.getFile().isDirectory(getLinkOption(followSymlinks));
123+
}
124+
125+
@Specialization
126+
boolean testNone(PDirEntry self, @SuppressWarnings("unused") PNone followSymlinks) {
127+
return testBool(self, true);
128+
}
129+
130+
@Specialization
131+
boolean testAny(Object self, Object followSymlinks,
132+
@Cached("createIfTrueNode()") CastToBooleanNode isTrue) {
133+
if (self instanceof PDirEntry) {
134+
return testBool((PDirEntry) self, isTrue.executeWith(followSymlinks));
135+
} else {
136+
throw raise(PythonBuiltinClassType.TypeError, "descriptor 'is_dir' requires a 'posix.DirEntry' object but received a '%p'", self);
137+
}
113138
}
114139
}
115140

0 commit comments

Comments
 (0)