Skip to content

Commit d399bb8

Browse files
committed
allow setting __class__ if value module type
1 parent 9a87a39 commit d399bb8

File tree

1 file changed

+27
-12
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object

1 file changed

+27
-12
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,12 @@
100100
import com.oracle.graal.python.nodes.util.CannotCastException;
101101
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
102102
import com.oracle.graal.python.nodes.util.SplitArgsNode;
103+
import com.oracle.graal.python.runtime.PythonContext;
103104
import com.oracle.truffle.api.CompilerDirectives;
104105
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
105106
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
106107
import com.oracle.truffle.api.dsl.Cached;
108+
import com.oracle.truffle.api.dsl.CachedContext;
107109
import com.oracle.truffle.api.dsl.Fallback;
108110
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
109111
import com.oracle.truffle.api.dsl.ImportStatic;
@@ -138,38 +140,51 @@ Object getClass(Object self, @SuppressWarnings("unused") PNone value,
138140
return getClass.execute(self);
139141
}
140142

141-
@Specialization
142-
Object setClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") PythonBuiltinClass klass) {
143-
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
144-
}
145-
146143
@Specialization(guards = "isNativeClass(klass)")
147144
Object setClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object klass) {
148145
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
149146
}
150147

151-
@Specialization(guards = "isPythonClass(value)")
148+
@Specialization(guards = "isPythonClass(value) || isPythonBuiltinClassType(value)")
152149
PNone setClass(VirtualFrame frame, PythonObject self, Object value,
153150
@CachedLibrary(limit = "2") PythonObjectLibrary lib1,
154151
@Cached("create()") BranchProfile errorValueBranch,
155-
@Cached("create()") BranchProfile errorSelfBranch) {
156-
if (value instanceof PythonBuiltinClass || PGuards.isNativeClass(value)) {
152+
@Cached("create()") BranchProfile errorSelfBranch,
153+
@CachedContext(PythonLanguage.class) PythonContext ctx) {
154+
if (isBuiltinClassNotModule(value) || PGuards.isNativeClass(value)) {
157155
errorValueBranch.enter();
158156
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
159157
}
160158
Object lazyClass = lib1.getLazyPythonClass(self);
161-
if (lazyClass instanceof PythonBuiltinClassType || lazyClass instanceof PythonBuiltinClass || PGuards.isNativeClass(lazyClass)) {
159+
if (isBuiltinClassNotModule(lazyClass) || PGuards.isNativeClass(lazyClass)) {
162160
errorSelfBranch.enter();
163161
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
164162
}
165163

166-
getCheckCompatibleForAssigmentNode().execute(frame, lazyClass, value);
164+
setClass(frame, self, lazyClass, value, ctx, lib1);
165+
return PNone.NONE;
166+
}
167+
168+
private void setClass(VirtualFrame frame, PythonObject self, Object lazyClass, Object value, PythonContext ctx, PythonObjectLibrary lib1) {
169+
if (lazyClass instanceof PythonBuiltinClassType) {
170+
getCheckCompatibleForAssigmentNode().execute(frame, ctx.getCore().lookupType((PythonBuiltinClassType) lazyClass), value);
171+
} else {
172+
getCheckCompatibleForAssigmentNode().execute(frame, lazyClass, value);
173+
}
167174

168175
lib1.setLazyPythonClass(self, value);
169-
return PNone.NONE;
170176
}
171177

172-
@Specialization(guards = {"isPythonClass(value)", "!isPythonObject(self)"})
178+
private static boolean isBuiltinClassNotModule(Object lazyClass) {
179+
if (lazyClass instanceof PythonBuiltinClass) {
180+
return ((PythonBuiltinClass) lazyClass).getType() != PythonBuiltinClassType.PythonModule;
181+
} else if (lazyClass instanceof PythonBuiltinClassType) {
182+
return ((PythonBuiltinClassType) lazyClass) != PythonBuiltinClassType.PythonModule;
183+
}
184+
return false;
185+
}
186+
187+
@Specialization(guards = {"isPythonClass(value) || isPythonBuiltinClassType(value)", "!isPythonObject(self)"})
173188
Object getClass(@SuppressWarnings("unused") Object self, @SuppressWarnings("unused") Object value) {
174189
throw raise(TypeError, ErrorMessages.CLASS_ASSIGMENT_ONLY_SUPPORTED_FOR_HEAP_TYPES_OR_MODTYPE_SUBCLASSES);
175190
}

0 commit comments

Comments
 (0)