Skip to content

Commit f36e4f0

Browse files
committed
MethodBuiltins: add __qualname__ and __name__ builtins
1 parent a717b3c commit f36e4f0

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodBuiltins.java

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
3232
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__FUNC__;
3333
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__KWDEFAULTS__;
34+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
35+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__QUALNAME__;
3436
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__;
3537
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GET__;
3638
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REDUCE__;
@@ -46,8 +48,10 @@
4648
import com.oracle.graal.python.builtins.objects.PNone;
4749
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
4850
import com.oracle.graal.python.builtins.objects.function.PKeyword;
51+
import com.oracle.graal.python.builtins.objects.module.PythonModule;
4952
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
5053
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
54+
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
5155
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
5256
import com.oracle.graal.python.nodes.ErrorMessages;
5357
import com.oracle.graal.python.nodes.SpecialAttributeNames;
@@ -60,6 +64,8 @@
6064
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
6165
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
6266
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
67+
import com.oracle.graal.python.nodes.util.CannotCastException;
68+
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
6369
import com.oracle.graal.python.runtime.exception.PException;
6470
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
6571
import com.oracle.truffle.api.dsl.Cached;
@@ -133,7 +139,7 @@ public abstract static class ReprNode extends PythonUnaryBuiltinNode {
133139
@Specialization(limit = "3")
134140
Object reprMethod(VirtualFrame frame, PMethod self,
135141
@CachedLibrary("self.getSelf()") PythonObjectLibrary lib,
136-
@Cached("createGetAttributeNode()") GetAttributeNode getNameAttrNode,
142+
@Cached("create(__QUALNAME__)") GetAttributeNode getNameAttrNode,
137143
@Cached GetNameNode getTypeNameNode) {
138144
String typeName = getTypeNameNode.execute(lib.getLazyPythonClass(self.getSelf()));
139145
return strFormat("<bound method %s of %s object at 0x%x>", getNameAttrNode.executeObject(frame, self.getFunction()), typeName, PythonAbstractObject.systemHashCode(self.getSelf()));
@@ -143,10 +149,6 @@ Object reprMethod(VirtualFrame frame, PMethod self,
143149
private static String strFormat(String fmt, Object... objects) {
144150
return String.format(fmt, objects);
145151
}
146-
147-
protected static GetAttributeNode createGetAttributeNode() {
148-
return GetAttributeNode.create(SpecialAttributeNames.__QUALNAME__, null);
149-
}
150152
}
151153

152154
@Builtin(name = __DEFAULTS__, minNumOfPositionalArgs = 1, isGetter = true)
@@ -194,4 +196,47 @@ PMethod doGeneric(@SuppressWarnings("unused") PMethod self, Object obj, @Suppres
194196
return factory().createMethod(obj, self.getFunction());
195197
}
196198
}
199+
200+
@Builtin(name = __NAME__, minNumOfPositionalArgs = 1, isGetter = true)
201+
@GenerateNodeFactory
202+
public abstract static class MethodName extends PythonUnaryBuiltinNode {
203+
@Specialization
204+
Object getName(VirtualFrame frame, PMethod method,
205+
@Cached("create(__NAME__)") GetAttributeNode getNameAttrNode) {
206+
return getNameAttrNode.executeObject(frame, method.getFunction());
207+
}
208+
}
209+
210+
@Builtin(name = __QUALNAME__, minNumOfPositionalArgs = 1, isGetter = true)
211+
@GenerateNodeFactory
212+
public abstract static class MethodQualName extends PythonUnaryBuiltinNode {
213+
@Specialization
214+
Object getQualName(VirtualFrame frame, PMethod method,
215+
@Cached("create(__QUALNAME__)") GetAttributeNode getQualNameAttrNode,
216+
@Cached("create(__NAME__)") GetAttributeNode getNameAttrNode,
217+
@Cached TypeNodes.IsTypeNode isTypeNode,
218+
@Cached CastToJavaStringNode castToJavaStringNode,
219+
@CachedLibrary("method.getSelf()") PythonObjectLibrary pol) {
220+
Object self = method.getSelf();
221+
String selfName = castToJavaStringNode.execute(getNameAttrNode.executeObject(frame, self));
222+
if (self instanceof PythonModule) {
223+
return selfName;
224+
}
225+
226+
Object type = isTypeNode.execute(self) ? self: pol.getLazyPythonClass(self);
227+
String typeQualName;
228+
try {
229+
typeQualName = castToJavaStringNode.execute(getQualNameAttrNode.executeObject(frame, type));
230+
} catch (CannotCastException e) {
231+
throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A, __QUALNAME__, "unicode object");
232+
}
233+
234+
return getQualNameGeneric(typeQualName, selfName);
235+
}
236+
237+
@TruffleBoundary
238+
private static Object getQualNameGeneric(String typeQualName, String name) {
239+
return String.format("%s.%s", typeQualName, name);
240+
}
241+
}
197242
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ public abstract class ErrorMessages {
299299
public static final String INVALID_USE_OF_W_FORMAT_CHAR = "invalid use of 'w' format character";
300300
public static final String IS_EMPTY = "%s is empty";
301301
public static final String IS_NOT_IN_RANGE = "%s is not in range";
302+
public static final String IS_NOT_A = "%s is not a %s";
302303
public static final String D_IS_NOT_IN_RANGE = "%d is not in range";
303304
public static final String INIT_TAKES_ONE_ARG = "%N.__init__() takes exactly one argument (the instance to initialize)";
304305
public static final String INIT_TAKES_ONE_ARG_OBJECT = "object.__init__() takes exactly one argument (the instance to initialize)";

0 commit comments

Comments
 (0)