|
27 | 27 | package com.oracle.graal.python.builtins.objects.function;
|
28 | 28 |
|
29 | 29 | import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DEFAULTS__;
|
| 30 | +import static com.oracle.graal.python.nodes.SpecialAttributeNames.__KWDEFAULTS__; |
30 | 31 | import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
|
31 | 32 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__REDUCE__;
|
32 | 33 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__REPR__;
|
|
41 | 42 | import com.oracle.graal.python.builtins.PythonBuiltins;
|
42 | 43 | import com.oracle.graal.python.builtins.objects.PNone;
|
43 | 44 | import com.oracle.graal.python.builtins.objects.function.FunctionBuiltinsFactory.GetFunctionDefaultsNodeFactory;
|
| 45 | +import com.oracle.graal.python.builtins.objects.function.FunctionBuiltinsFactory.GetFunctionKeywordDefaultsNodeFactory; |
44 | 46 | import com.oracle.graal.python.builtins.objects.str.PString;
|
45 | 47 | import com.oracle.graal.python.builtins.objects.tuple.PTuple;
|
46 | 48 | import com.oracle.graal.python.nodes.argument.ReadKeywordNode;
|
@@ -140,7 +142,7 @@ Object setName(Object self, Object value) {
|
140 | 142 | @Builtin(name = __DEFAULTS__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
|
141 | 143 | @GenerateNodeFactory
|
142 | 144 | public abstract static class GetFunctionDefaultsNode extends PythonBinaryBuiltinNode {
|
143 |
| - protected final ConditionProfile nullDefaultsProfile = ConditionProfile.createBinaryProfile(); |
| 145 | + private final ConditionProfile nullDefaultsProfile = ConditionProfile.createBinaryProfile(); |
144 | 146 |
|
145 | 147 | @TruffleBoundary
|
146 | 148 | private static Object[] extractDefaults(PFunction function) {
|
@@ -181,10 +183,52 @@ public static GetFunctionDefaultsNode create() {
|
181 | 183 | }
|
182 | 184 | }
|
183 | 185 |
|
| 186 | + @Builtin(name = __KWDEFAULTS__, fixedNumOfPositionalArgs = 1, isGetter = true) |
| 187 | + @GenerateNodeFactory |
| 188 | + public abstract static class GetFunctionKeywordDefaultsNode extends PythonUnaryBuiltinNode { |
| 189 | + @TruffleBoundary |
| 190 | + private static PKeyword[] extractDefaults(PFunction function) { |
| 191 | + ArrayList<PKeyword> kwdefaults = new ArrayList<>(); |
| 192 | + List<ReadKeywordNode> readKeywordNodes = NodeUtil.findAllNodeInstances(function.getFunctionRootNode(), ReadKeywordNode.class); |
| 193 | + for (ReadKeywordNode readKeywordNode : readKeywordNodes) { |
| 194 | + if (!readKeywordNode.canBePositional()) { |
| 195 | + Object defaultValue = readKeywordNode.getDefaultValue(); |
| 196 | + if (defaultValue != null) { |
| 197 | + kwdefaults.add(new PKeyword(readKeywordNode.getName(), defaultValue)); |
| 198 | + } |
| 199 | + } |
| 200 | + } |
| 201 | + |
| 202 | + return kwdefaults.toArray(new PKeyword[0]); |
| 203 | + } |
| 204 | + |
| 205 | + @Specialization(guards = "!takesVarargs(self)") |
| 206 | + Object doNoKeywordOnlyArgs(@SuppressWarnings("unused") PFunction self) { |
| 207 | + return PNone.NONE; |
| 208 | + } |
| 209 | + |
| 210 | + @Specialization(guards = "takesVarargs(self)") |
| 211 | + Object doGeneric(PFunction self) { |
| 212 | + PKeyword[] kwdefaults = extractDefaults(self); |
| 213 | + if (kwdefaults.length > 0) { |
| 214 | + return factory().createDict(kwdefaults); |
| 215 | + } |
| 216 | + return PNone.NONE; |
| 217 | + } |
| 218 | + |
| 219 | + protected static boolean takesVarargs(PFunction self) { |
| 220 | + return self.getArity().takesVarArgs(); |
| 221 | + } |
| 222 | + |
| 223 | + public static GetFunctionKeywordDefaultsNode create() { |
| 224 | + return GetFunctionKeywordDefaultsNodeFactory.create(); |
| 225 | + } |
| 226 | + } |
| 227 | + |
184 | 228 | @Builtin(name = __REDUCE__, fixedNumOfPositionalArgs = 1)
|
185 | 229 | @GenerateNodeFactory
|
186 | 230 | public abstract static class ReduceNode extends PythonUnaryBuiltinNode {
|
187 |
| - @Specialization |
| 231 | + @Fallback |
188 | 232 | Object doGeneric(@SuppressWarnings("unused") Object obj) {
|
189 | 233 | throw raise(TypeError, "can't pickle function objects");
|
190 | 234 | }
|
|
0 commit comments