Skip to content

Commit 80fbc04

Browse files
committed
Fix: Correctly compute qualified name of nested classes.
1 parent 8107662 commit 80fbc04

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_metaclass.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,17 @@ def __init__(self, a, b):
128128
assert len(global_log) == 4
129129
assert global_log[2] == ['__call__', MyClass, (1, 2), {}]
130130
assert global_log[3] == ['MyKlass object', 1, 2]
131+
132+
133+
class A:
134+
class B:
135+
pass
136+
137+
138+
def test_nested_class():
139+
assert A.__name__ == "A"
140+
assert A.__qualname__ == "A"
141+
assert A.__module__ == __name__
142+
assert A.B.__name__ == "B"
143+
assert A.B.__qualname__ == "A.B"
144+
assert A.B.__module__ == __name__

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__BASES__;
3030
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__CLASS__;
3131
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
32+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MODULE__;
3233
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MRO__;
3334
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.__CALL__;
3537
import static com.oracle.graal.python.nodes.SpecialMethodNames.__DELETE__;
3638
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__;
@@ -39,6 +41,7 @@
3941
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INSTANCECHECK__;
4042
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEW__;
4143
import static com.oracle.graal.python.nodes.SpecialMethodNames.__PREPARE__;
44+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REPR__;
4245
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SET__;
4346
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SUBCLASSCHECK__;
4447
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SUBCLASSES__;
@@ -62,7 +65,6 @@
6265
import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy;
6366
import com.oracle.graal.python.builtins.objects.object.PythonObject;
6467
import com.oracle.graal.python.builtins.objects.type.TypeBuiltinsFactory.CallNodeFactory;
65-
import com.oracle.graal.python.nodes.SpecialMethodNames;
6668
import com.oracle.graal.python.nodes.argument.positional.PositionalArgumentsNode;
6769
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
6870
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
@@ -101,14 +103,25 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
101103
return TypeBuiltinsFactory.getFactories();
102104
}
103105

104-
@Builtin(name = SpecialMethodNames.__REPR__, fixedNumOfPositionalArgs = 1)
106+
@Builtin(name = __REPR__, fixedNumOfPositionalArgs = 1)
105107
@GenerateNodeFactory
106108
public abstract static class ReprNode extends PythonUnaryBuiltinNode {
107109

108110
@Specialization
111+
public String repr(PythonClass self,
112+
@Cached("create()") ReadAttributeFromObjectNode readModuleNode,
113+
@Cached("create()") ReadAttributeFromObjectNode readQualNameNode) {
114+
Object moduleName = readModuleNode.execute(self, __MODULE__);
115+
Object qualName = readQualNameNode.execute(self, __QUALNAME__);
116+
return concat(moduleName, qualName);
117+
}
118+
109119
@TruffleBoundary
110-
public String repr(PythonClass self) {
111-
return self.toString();
120+
private static String concat(Object moduleName, Object qualName) {
121+
if (moduleName != PNone.NO_VALUE) {
122+
return String.format("<class '%s.%s'>", moduleName, qualName);
123+
}
124+
return String.format("<class '%s'>", qualName);
112125
}
113126
}
114127

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/PythonTreeTranslator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,9 @@ private static String calculateQualname(Python3Parser.ClassdefContext ctx) {
16971697
Python3Parser.FuncdefContext funcdefContext = (Python3Parser.FuncdefContext) parent;
16981698
stack.push("<locals>");
16991699
stack.push(funcdefContext.NAME().getText());
1700+
} else if (parent instanceof Python3Parser.ClassdefContext) {
1701+
Python3Parser.ClassdefContext classdefContext = (Python3Parser.ClassdefContext) parent;
1702+
stack.push(classdefContext.NAME().getText());
17001703
}
17011704

17021705
parent = parent.getParent();

0 commit comments

Comments
 (0)