Skip to content

Commit d523173

Browse files
committed
[GR-23273] Make test_abc pass
PullRequest: graalpython/1444
2 parents f8bd1bb + 05c0883 commit d523173

File tree

9 files changed

+180
-11
lines changed

9 files changed

+180
-11
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,48 @@
11
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_ABC_has___slots__
2+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_ABC_has___slots__
3+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_ABC_helper
4+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_ABC_helper
5+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractclassmethod_basics
6+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractclassmethod_basics
7+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractmethod_basics
28
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractmethod_basics
9+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractmethod_integration
10+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractmethod_integration
11+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractproperty_basics
12+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractproperty_basics
13+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractstaticmethod_basics
14+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_abstractstaticmethod_basics
315
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_all_new_methods_are_called
16+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_all_new_methods_are_called
17+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_customdescriptors_with_abstractmethod
18+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_customdescriptors_with_abstractmethod
19+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_descriptors_with_abstractmethod
20+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_descriptors_with_abstractmethod
21+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_isinstance_invalidation
422
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_isinstance_invalidation
523
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_issubclass_bad_arguments
24+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_issubclass_bad_arguments
25+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_metaclass_abc
626
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_metaclass_abc
727
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_register_as_class_deco
28+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_register_as_class_deco
829
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_register_non_class
30+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_register_non_class
31+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_basics
932
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_basics
1033
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_builtins
34+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_builtins
35+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_edge_cases
1136
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_edge_cases
1237
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_transitiveness
38+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_registration_transitiveness
39+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_tricky_new_works
1340
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABC.test_tricky_new_works
1441
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABCWithInitSubclass.test_works_with_init_subclass
42+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestABCWithInitSubclass.test_works_with_init_subclass
43+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestLegacyAPI.test_abstractclassmethod_basics
44+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestLegacyAPI.test_abstractclassmethod_basics
45+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestLegacyAPI.test_abstractproperty_basics
46+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestLegacyAPI.test_abstractproperty_basics
47+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestLegacyAPI.test_abstractstaticmethod_basics
48+
*graalpython.lib-python.3.test.test_abc.test_factory.<locals>.TestLegacyAPI.test_abstractstaticmethod_basics

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import static com.oracle.graal.python.nodes.ErrorMessages.TAKES_EXACTLY_D_ARGUMENTS_D_GIVEN;
6767
import static com.oracle.graal.python.nodes.PGuards.isInteger;
6868
import static com.oracle.graal.python.nodes.PGuards.isNoValue;
69+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__ABSTRACTMETHODS__;
6970
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__BASICSIZE__;
7071
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__CLASSCELL__;
7172
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICTOFFSET__;
@@ -180,6 +181,7 @@
180181
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
181182
import com.oracle.graal.python.builtins.objects.type.PythonClass;
182183
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
184+
import com.oracle.graal.python.builtins.objects.type.TypeFlags;
183185
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
184186
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBestBaseClassNode;
185187
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetItemsizeNode;
@@ -190,6 +192,8 @@
190192
import com.oracle.graal.python.nodes.BuiltinNames;
191193
import com.oracle.graal.python.nodes.ErrorMessages;
192194
import com.oracle.graal.python.nodes.PGuards;
195+
import com.oracle.graal.python.nodes.PNodeWithContext;
196+
import com.oracle.graal.python.nodes.PRaiseNode;
193197
import com.oracle.graal.python.nodes.SpecialAttributeNames;
194198
import com.oracle.graal.python.nodes.SpecialMethodNames;
195199
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
@@ -199,6 +203,7 @@
199203
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
200204
import com.oracle.graal.python.nodes.attributes.SetAttributeNode;
201205
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
206+
import com.oracle.graal.python.nodes.builtins.ListNodes;
202207
import com.oracle.graal.python.nodes.builtins.TupleNodes;
203208
import com.oracle.graal.python.nodes.call.CallNode;
204209
import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode;
@@ -1629,11 +1634,34 @@ public abstract static class ObjectNode extends PythonVarargsBuiltinNode {
16291634
@Child private SplitArgsNode splitArgsNode;
16301635
@Child private LookupAttributeInMRONode lookupInit;
16311636
@Child private LookupAttributeInMRONode lookupNew;
1637+
@Child private ReportAbstractClassNode reportAbstractClassNode;
16321638
@CompilationFinal private ValueProfile profileInit;
16331639
@CompilationFinal private ValueProfile profileNew;
16341640
@CompilationFinal private ValueProfile profileInitFactory;
16351641
@CompilationFinal private ValueProfile profileNewFactory;
16361642

1643+
abstract static class ReportAbstractClassNode extends PNodeWithContext {
1644+
public abstract PException execute(VirtualFrame frame, Object type);
1645+
1646+
@Specialization
1647+
static PException report(VirtualFrame frame, Object type,
1648+
@CachedLibrary(limit = "2") PythonObjectLibrary lib,
1649+
@Cached ReadAttributeFromObjectNode readAttributeFromObjectNode,
1650+
@Cached CastToJavaStringNode cast,
1651+
@Cached ListNodes.ConstructListNode constructListNode,
1652+
@Cached PRaiseNode raiseNode) {
1653+
PList list = constructListNode.execute(readAttributeFromObjectNode.execute(type, __ABSTRACTMETHODS__));
1654+
int methodCount = lib.lengthWithFrame(list, frame);
1655+
lib.lookupAndCallRegularMethod(list, frame, "sort");
1656+
String joined = cast.execute(lib.lookupAndCallRegularMethod(", ", frame, "join", list));
1657+
throw raiseNode.raise(TypeError, "Can't instantiate abstract class %N with abstract method%s %s", type, methodCount > 1 ? "s" : "", joined);
1658+
}
1659+
1660+
public static ReportAbstractClassNode create() {
1661+
return BuiltinConstructorsFactory.ObjectNodeFactory.ReportAbstractClassNodeGen.create();
1662+
}
1663+
}
1664+
16371665
@Override
16381666
public final Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
16391667
if (splitArgsNode == null) {
@@ -1644,8 +1672,11 @@ public final Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused"
16441672
}
16451673

16461674
@Specialization(guards = {"!self.needsNativeAllocation()"})
1647-
Object doManagedObject(PythonManagedClass self, Object[] varargs, PKeyword[] kwargs) {
1675+
Object doManagedObject(VirtualFrame frame, PythonManagedClass self, Object[] varargs, PKeyword[] kwargs) {
16481676
checkExcessArgs(self, varargs, kwargs);
1677+
if (self.isAbstractClass()) {
1678+
throw getReportAbstractClassNode().execute(frame, self);
1679+
}
16491680
return factory().createPythonObject(self);
16501681
}
16511682

@@ -1656,16 +1687,23 @@ Object doBuiltinTypeType(PythonBuiltinClassType self, Object[] varargs, PKeyword
16561687
}
16571688

16581689
@Specialization(guards = "self.needsNativeAllocation()")
1659-
Object doNativeObjectIndirect(PythonManagedClass self, Object[] varargs, PKeyword[] kwargs,
1690+
Object doNativeObjectIndirect(VirtualFrame frame, PythonManagedClass self, Object[] varargs, PKeyword[] kwargs,
16601691
@Cached("create()") GetMroNode getMroNode) {
16611692
checkExcessArgs(self, varargs, kwargs);
1693+
if (self.isAbstractClass()) {
1694+
throw getReportAbstractClassNode().execute(frame, self);
1695+
}
16621696
Object nativeBaseClass = findFirstNativeBaseClass(getMroNode.execute(self));
16631697
return callNativeGenericNewNode(nativeBaseClass, varargs, kwargs);
16641698
}
16651699

16661700
@Specialization(guards = "isNativeClass(self)")
1667-
Object doNativeObjectIndirect(Object self, Object[] varargs, PKeyword[] kwargs) {
1701+
Object doNativeObjectDirect(VirtualFrame frame, Object self, Object[] varargs, PKeyword[] kwargs,
1702+
@Cached TypeNodes.GetTypeFlagsNode getTypeFlagsNode) {
16681703
checkExcessArgs(self, varargs, kwargs);
1704+
if ((getTypeFlagsNode.execute(self) & TypeFlags.IS_ABSTRACT) != 0) {
1705+
throw getReportAbstractClassNode().execute(frame, self);
1706+
}
16691707
return callNativeGenericNewNode(self, varargs, kwargs);
16701708
}
16711709

@@ -1750,6 +1788,14 @@ private void checkExcessArgs(Object type, Object[] varargs, PKeyword[] kwargs) {
17501788
}
17511789
}
17521790
}
1791+
1792+
private ReportAbstractClassNode getReportAbstractClassNode() {
1793+
if (reportAbstractClassNode == null) {
1794+
CompilerDirectives.transferToInterpreterAndInvalidate();
1795+
reportAbstractClassNode = insert(ReportAbstractClassNode.create());
1796+
}
1797+
return reportAbstractClassNode;
1798+
}
17531799
}
17541800

17551801
// range(stop)

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
4545
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__FUNC__;
4646
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__;
47+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ISABSTRACTMETHOD__;
4748

4849
import java.util.List;
4950

@@ -66,8 +67,10 @@
6667
import com.oracle.truffle.api.dsl.ImportStatic;
6768
import com.oracle.truffle.api.dsl.NodeFactory;
6869
import com.oracle.truffle.api.dsl.Specialization;
70+
import com.oracle.truffle.api.frame.VirtualFrame;
6971
import com.oracle.truffle.api.interop.UnsupportedMessageException;
7072
import com.oracle.truffle.api.library.CachedLibrary;
73+
import com.oracle.truffle.api.profiles.ConditionProfile;
7174

7275
@CoreFunctions(extendClasses = {PythonBuiltinClassType.PStaticmethod, PythonBuiltinClassType.PClassmethod})
7376
public class DecoratedMethodBuiltins extends PythonBuiltins {
@@ -134,4 +137,19 @@ protected Object setDict(@SuppressWarnings("unused") PDecoratedMethod self, Obje
134137
throw raise(TypeError, ErrorMessages.DICT_MUST_BE_SET_TO_DICT, mapping);
135138
}
136139
}
140+
141+
@Builtin(name = __ISABSTRACTMETHOD__, minNumOfPositionalArgs = 1, isGetter = true)
142+
@GenerateNodeFactory
143+
abstract static class IsAbstractMethodNode extends PythonUnaryBuiltinNode {
144+
@Specialization
145+
static boolean isAbstract(VirtualFrame frame, PDecoratedMethod self,
146+
@CachedLibrary(limit = "4") PythonObjectLibrary lib,
147+
@Cached ConditionProfile hasAttrProfile) {
148+
Object result = lib.lookupAttribute(self.getCallable(), frame, __ISABSTRACTMETHOD__);
149+
if (hasAttrProfile.profile(result != PNone.NO_VALUE)) {
150+
return lib.isTrue(result, frame);
151+
}
152+
return false;
153+
}
154+
}
137155
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ public abstract class PythonManagedClass extends PythonObject implements PythonA
6565

6666
@CompilationFinal private MroSequenceStorage methodResolutionOrder;
6767

68+
private boolean abstractClass;
69+
6870
private final Set<PythonAbstractClass> subClasses = Collections.newSetFromMap(new WeakHashMap<PythonAbstractClass, Boolean>());
6971
@CompilationFinal private Shape instanceShape;
7072
private String name;
@@ -176,6 +178,14 @@ public void setName(String name) {
176178
this.name = name;
177179
}
178180

181+
public boolean isAbstractClass() {
182+
return abstractClass;
183+
}
184+
185+
public void setAbstractClass(boolean abstractClass) {
186+
this.abstractClass = abstractClass;
187+
}
188+
179189
private boolean computeNeedsNativeAllocation() {
180190
for (PythonAbstractClass cls : getMethodResolutionOrder().getInternalClassArray()) {
181191
if (PGuards.isNativeClass(cls)) {

0 commit comments

Comments
 (0)