Skip to content

Commit 2319c0d

Browse files
committed
[GR-23218] Make test_descr pass - mro().
PullRequest: graalpython/1141
2 parents 313922b + 2c3a904 commit 2319c0d

File tree

9 files changed

+280
-149
lines changed

9 files changed

+280
-149
lines changed

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class C(A, B):
6565
assert C.__base__ == B
6666

6767
#-----------------------------------------------
68-
68+
6969
class A(object):
7070
pass
7171

@@ -79,9 +79,9 @@ class C(A, B):
7979

8080
C = type('C', (B, int), {'spam': lambda self: 'spam%s' % self})
8181
assert C.__base__ == int
82-
82+
8383
#-----------------------------------------------
84-
84+
8585
class A (object): pass
8686

8787
class BB (A): pass
@@ -96,7 +96,7 @@ class D (B, C): pass
9696
assert D.__base__ == C
9797

9898
#-----------------------------------------------
99-
99+
100100
class A: pass
101101

102102
class B: pass
@@ -110,7 +110,7 @@ class C(A): pass
110110
assert B.__subclasses__() == [C]
111111

112112
#-----------------------------------------------
113-
113+
114114
class A: pass
115115

116116
class B: pass
@@ -133,7 +133,7 @@ class C(A, B): pass
133133
assert B.__subclasses__() == [C]
134134

135135
#-----------------------------------------------
136-
136+
137137
# class A: pass
138138
#
139139
# class B: pass
@@ -155,5 +155,16 @@ class MyStr(str):
155155
A = type('A', (), {
156156
MyStr("x"): 42
157157
})
158-
assert A.x == 42
159158
assert any(type(k) == MyStr for k in A.__dict__.keys())
159+
160+
def test_mro():
161+
class M(type):
162+
def mro(cls):
163+
assert type.mro(cls) == [cls, A, B, object]
164+
return [cls, B, A, object]
165+
166+
class A: pass
167+
class B: pass
168+
class C(A, B, metaclass = M): pass
169+
170+
assert C.__mro__ == (C, B, A, object)

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_descr.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_abstractmethods
2+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_altmro
23
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_assign_slice
34
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_binary_operator_override
45
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_bpo25750
@@ -36,6 +37,7 @@
3637
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_multiple_inheritance
3738
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_mutable_bases
3839
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_mutable_bases_catch_mro_conflict
40+
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_mutable_bases_with_failing_mro
3941
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_mutable_names
4042
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_newslots
4143
*graalpython.lib-python.3.test.test_descr.ClassPropertiesAndMethods.test_not_implemented

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,15 @@
3434
import java.util.WeakHashMap;
3535

3636
import com.oracle.graal.python.PythonLanguage;
37+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
3738
import com.oracle.graal.python.builtins.objects.PNone;
3839
import com.oracle.graal.python.builtins.objects.cext.PythonClassNativeWrapper;
3940
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4041
import com.oracle.graal.python.builtins.objects.type.TypeNodes.ComputeMroNode;
4142
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesNode;
43+
import com.oracle.graal.python.nodes.ErrorMessages;
4244
import com.oracle.graal.python.nodes.PGuards;
45+
import com.oracle.graal.python.nodes.PRaiseNode;
4346
import com.oracle.graal.python.runtime.exception.PException;
4447
import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage;
4548
import com.oracle.truffle.api.Assumption;
@@ -82,6 +85,7 @@ protected PythonManagedClass(Object typeClass, DynamicObject storage, Shape inst
8285

8386
// Compute MRO
8487
this.methodResolutionOrder.setInternalArrayObject(ComputeMroNode.doSlowPath(this));
88+
this.methodResolutionOrder.setInitialized();
8589
this.needsNativeAllocation = computeNeedsNativeAllocation();
8690

8791
setAttribute(__NAME__, getBaseName(name));
@@ -176,12 +180,16 @@ private void unsafeSetSuperClass(PythonAbstractClass... newBaseClasses) {
176180
assert getBaseClasses() == null || getBaseClasses().length == 0;
177181
this.baseClasses = newBaseClasses;
178182

183+
for (PythonAbstractClass base : getBaseClasses()) {
184+
if (base instanceof PythonManagedClass && !((PythonManagedClass) base).getMethodResolutionOrder().isInitialized()) {
185+
throw PRaiseNode.getUncached().raise(TypeError, ErrorMessages.CANNOT_EXTEND_INCOMPLETE_P, base);
186+
}
187+
}
179188
for (PythonAbstractClass base : getBaseClasses()) {
180189
if (base != null) {
181190
GetSubclassesNode.getUncached().execute(base).add(this);
182191
}
183192
}
184-
this.methodResolutionOrder.setInternalArrayObject(ComputeMroNode.doSlowPath(this));
185193
}
186194

187195
@TruffleBoundary

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode;
134134
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
135135
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBestBaseClassNode;
136+
import static com.oracle.graal.python.nodes.SpecialMethodNames.MRO;
136137
import com.oracle.truffle.api.profiles.BranchProfile;
137138
import com.oracle.truffle.api.profiles.ConditionProfile;
138139

@@ -178,12 +179,17 @@ private static String concat(Object moduleName, Object qualName) {
178179
abstract static class MroAttrNode extends PythonBuiltinNode {
179180
@Specialization
180181
Object doit(Object klass,
181-
@Cached("create()") TypeNodes.GetMroNode getMroNode) {
182-
return factory().createTuple(getMroNode.execute(klass));
182+
@Cached("create()") TypeNodes.GetMroNode getMroNode,
183+
@Cached TypeNodes.GetMroStorageNode getMroStorageNode) {
184+
if (klass instanceof PythonManagedClass && !getMroStorageNode.execute(klass).isInitialized()) {
185+
return PNone.NONE;
186+
}
187+
PythonAbstractClass[] mro = getMroNode.execute(klass);
188+
return factory().createTuple(mro);
183189
}
184190
}
185191

186-
@Builtin(name = "mro", minNumOfPositionalArgs = 1)
192+
@Builtin(name = MRO, minNumOfPositionalArgs = 1)
187193
@GenerateNodeFactory
188194
public abstract static class MroNode extends PythonBuiltinNode {
189195
@Specialization(guards = "lib.isLazyPythonClass(klass)")
@@ -197,7 +203,7 @@ Object doit(Object klass,
197203
@Specialization(guards = "!lib.isLazyPythonClass(object)")
198204
Object doit(Object object,
199205
@SuppressWarnings("unused") @CachedLibrary(limit = "2") PythonObjectLibrary lib) {
200-
throw raise(TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_OBJ, "mro", "type", object);
206+
throw raise(TypeError, ErrorMessages.DESCRIPTOR_REQUIRES_OBJ, MRO, "type", object);
201207
}
202208
}
203209

@@ -597,12 +603,12 @@ Object setBases(VirtualFrame frame, PythonClass cls, PTuple value,
597603
}
598604
}
599605

600-
PythonAbstractClass newBestBase = getBestBase.execute(frame, baseClasses);
606+
LazyPythonClass newBestBase = getBestBase.execute(baseClasses);
601607
if (newBestBase == null) {
602608
return null;
603609
}
604610

605-
PythonAbstractClass oldBase = getBase.execute(frame, cls);
611+
LazyPythonClass oldBase = getBase.execute(cls);
606612
checkCompatibleForAssigment.execute(frame, oldBase, newBestBase);
607613

608614
cls.setSuperClass(baseClasses);
@@ -628,9 +634,9 @@ Object setBuiltin(@SuppressWarnings("unused") PythonBuiltinClass cls, @SuppressW
628634
@GenerateNodeFactory
629635
abstract static class BaseNode extends PythonBuiltinNode {
630636
@Specialization
631-
static Object base(VirtualFrame frame, Object self,
637+
static Object base(Object self,
632638
@Cached TypeNodes.GetBaseClassNode getBaseClassNode) {
633-
Object baseClass = getBaseClassNode.execute(frame, self);
639+
Object baseClass = getBaseClassNode.execute(self);
634640
return baseClass != null ? baseClass : PNone.NONE;
635641
}
636642
}

0 commit comments

Comments
 (0)