40
40
*/
41
41
package com .oracle .graal .python .builtins .objects .posix ;
42
42
43
+ import java .nio .file .LinkOption ;
43
44
import java .util .List ;
44
45
45
46
import com .oracle .graal .python .builtins .Builtin ;
51
52
import com .oracle .graal .python .nodes .SpecialMethodNames ;
52
53
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
53
54
import com .oracle .graal .python .nodes .attributes .WriteAttributeToObjectNode ;
55
+ import com .oracle .graal .python .nodes .expression .CastToBooleanNode ;
54
56
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
57
+ import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
55
58
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
56
59
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
57
60
import com .oracle .truffle .api .dsl .Cached ;
62
65
@ CoreFunctions (extendClasses = PythonBuiltinClassType .PDirEntry )
63
66
public class DirEntryBuiltins extends PythonBuiltins {
64
67
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
+
65
71
@ Override
66
72
protected List <? extends NodeFactory <? extends PythonBuiltinBaseNode >> getNodeFactories () {
67
73
return DirEntryBuiltinsFactory .getFactories ();
@@ -95,6 +101,10 @@ PNone inode(@SuppressWarnings("unused") PDirEntry self) {
95
101
}
96
102
}
97
103
104
+ private static LinkOption [] getLinkOption (boolean followSymlinks ) {
105
+ return followSymlinks ? NO_LINK_OPTIONS : NOFOLLOW_LINKS_OPTIONS ;
106
+ }
107
+
98
108
@ Builtin (name = "is_symlink" , minNumOfPositionalArgs = 1 )
99
109
@ GenerateNodeFactory
100
110
abstract static class IsSymNode extends PythonUnaryBuiltinNode {
@@ -104,12 +114,27 @@ boolean test(PDirEntry self) {
104
114
}
105
115
}
106
116
107
- @ Builtin (name = "is_dir" , minNumOfPositionalArgs = 1 )
117
+ @ Builtin (name = "is_dir" , minNumOfPositionalArgs = 1 , keywordOnlyNames = { "follow_symlinks" } )
108
118
@ GenerateNodeFactory
109
- abstract static class IsDirNode extends PythonUnaryBuiltinNode {
119
+ abstract static class IsDirNode extends PythonBinaryBuiltinNode {
110
120
@ 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
+ }
113
138
}
114
139
}
115
140
0 commit comments