Skip to content

Commit 54aa994

Browse files
committed
[GR-23254] Call __init__ when using raise <type>
PullRequest: graalpython/969
2 parents 1446e1f + 5063d06 commit 54aa994

File tree

8 files changed

+47
-173
lines changed

8 files changed

+47
-173
lines changed

graalpython/com.oracle.graal.python.benchmarks/python/micro/try-except-sized.py

Lines changed: 0 additions & 65 deletions
This file was deleted.

graalpython/com.oracle.graal.python.benchmarks/python/micro/try-except-store-sized.py

Lines changed: 0 additions & 66 deletions
This file was deleted.

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,9 +2924,14 @@ Object call() {
29242924
@Builtin(name = "BaseException", constructsClass = PythonBuiltinClassType.PBaseException, isPublic = true, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
29252925
@GenerateNodeFactory
29262926
public abstract static class BaseExceptionNode extends PythonBuiltinNode {
2927-
@Specialization
2928-
Object callGeneric(LazyPythonClass cls, Object[] varargs, @SuppressWarnings("unused") PKeyword[] kwargs) {
2929-
return factory().createBaseException(cls, factory().createTuple(varargs));
2927+
@Specialization(guards = "args.length == 0")
2928+
Object initNoArgs(LazyPythonClass cls, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs) {
2929+
return factory().createBaseException(cls);
2930+
}
2931+
2932+
@Specialization(guards = "args.length != 0")
2933+
Object initArgs(LazyPythonClass cls, Object[] args, @SuppressWarnings("unused") PKeyword[] kwargs) {
2934+
return factory().createBaseException(cls, factory().createTuple(args));
29302935
}
29312936
}
29322937

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/BaseExceptionBuiltins.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,13 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
8080
@Builtin(name = __INIT__, minNumOfPositionalArgs = 1, takesVarArgs = true)
8181
@GenerateNodeFactory
8282
public abstract static class InitNode extends PythonBuiltinNode {
83-
@Specialization
84-
Object init(PBaseException self, Object[] args) {
83+
@Specialization(guards = "args.length == 0")
84+
Object initNoArgs(@SuppressWarnings("unused") PBaseException self, @SuppressWarnings("unused") Object[] args) {
85+
return PNone.NONE;
86+
}
87+
88+
@Specialization(guards = "args.length != 0")
89+
Object initArgs(PBaseException self, Object[] args) {
8590
self.setArgs(factory().createTuple(args));
8691
return PNone.NONE;
8792
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/RaiseNode.java

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
3636
import com.oracle.graal.python.nodes.PGuards;
3737
import com.oracle.graal.python.nodes.PRaiseNode;
38+
import com.oracle.graal.python.nodes.call.CallNode;
3839
import com.oracle.graal.python.nodes.expression.ExpressionNode;
3940
import com.oracle.graal.python.nodes.util.ExceptionStateNodes.GetCaughtExceptionNode;
4041
import com.oracle.graal.python.runtime.exception.PException;
41-
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
4242
import com.oracle.truffle.api.dsl.Cached;
4343
import com.oracle.truffle.api.dsl.ImportStatic;
4444
import com.oracle.truffle.api.dsl.NodeChild;
@@ -66,16 +66,25 @@ void setCause(@SuppressWarnings("unused") VirtualFrame frame, PBaseException exc
6666
// raise * from <class>
6767
@Specialization
6868
void setCause(@SuppressWarnings("unused") VirtualFrame frame, PBaseException exception, LazyPythonClass causeClass,
69-
@Cached PythonObjectFactory factory,
7069
@Cached BranchProfile baseCheckFailedProfile,
7170
@Cached ValidExceptionNode validException,
71+
@Cached CallNode callConstructor,
7272
@Cached PRaiseNode raise) {
7373
if (!validException.execute(frame, causeClass)) {
7474
baseCheckFailedProfile.enter();
7575
throw raise.raise(PythonBuiltinClassType.TypeError, "exception causes must derive from BaseException");
7676
}
77-
PBaseException cause = factory.createBaseException(causeClass);
78-
exception.setCause(cause);
77+
Object cause = callConstructor.execute(causeClass);
78+
if (cause instanceof PBaseException) {
79+
exception.setCause((PBaseException) cause);
80+
} else {
81+
// msimacek: CPython currently (3.8.2) has a bug that it's not checking the type of
82+
// the value returned by the constructor, you can set a non-exception as a cause
83+
// this way and see the exception printer TypeError on it. I don't want to raise an
84+
// exception because CPython doesn't do it and I don't want to change the cause type
85+
// to Object either, because it's not meant to be that way.
86+
exception.setCause(null);
87+
}
7988
}
8089

8190
// raise * from None
@@ -146,22 +155,34 @@ private void checkBaseClass(VirtualFrame frame, PythonAbstractClass pythonClass,
146155
@Specialization(guards = "isNoValue(cause)")
147156
void doRaise(@SuppressWarnings("unused") VirtualFrame frame, PythonAbstractClass pythonClass, @SuppressWarnings("unused") PNone cause,
148157
@Cached ValidExceptionNode validException,
158+
@Cached CallNode callConstructor,
159+
@Cached BranchProfile constructorTypeErrorProfile,
149160
@Cached PRaiseNode raise) {
150161
checkBaseClass(frame, pythonClass, validException, raise);
151-
throw raise.raise(pythonClass);
162+
Object newException = callConstructor.execute(frame, pythonClass);
163+
if (newException instanceof PBaseException) {
164+
throw raise.raise((PBaseException) newException);
165+
} else {
166+
constructorTypeErrorProfile.enter();
167+
throw raise.raise(TypeError, "calling %s should have returned an instance of BaseException, not %p", pythonClass, newException);
168+
}
152169
}
153170

154171
// raise <class> from *
155172
@Specialization(guards = "!isNoValue(cause)")
156173
void doRaise(@SuppressWarnings("unused") VirtualFrame frame, PythonAbstractClass pythonClass, Object cause,
157-
@Cached PythonObjectFactory factory,
158174
@Cached ValidExceptionNode validException,
159175
@Cached PRaiseNode raise,
176+
@Cached CallNode callConstructor,
160177
@Cached SetExceptionCauseNode setExceptionCauseNode) {
161178
checkBaseClass(frame, pythonClass, validException, raise);
162-
PBaseException pythonException = factory.createBaseException(pythonClass);
163-
setExceptionCauseNode.execute(frame, pythonException, cause);
164-
throw raise.raise(pythonException);
179+
Object newException = callConstructor.execute(frame, pythonClass);
180+
if (newException instanceof PBaseException) {
181+
setExceptionCauseNode.execute(frame, (PBaseException) newException, cause);
182+
throw raise.raise((PBaseException) newException);
183+
} else {
184+
throw raise.raise(TypeError, "calling %s should have returned an instance of BaseException, not %p", pythonClass, newException);
185+
}
165186
}
166187

167188
// raise <invalid> [from *]

graalpython/lib-graalpython/exceptions.py

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,30 +55,14 @@ def SystemExit__init__(self, *args):
5555
SystemExit.__init__ = SystemExit__init__
5656
del SystemExit__init__
5757

58-
def ImportError__init__(self, msg, name=None, path=None):
59-
self.message = msg
58+
def ImportError__init__(self, msg=None, /, *args, name=None, path=None):
59+
self.msg = msg
6060
self.name = name
6161
self.path = path
6262

6363
ImportError.__init__ = ImportError__init__
6464
del ImportError__init__
6565

66-
def ModuleNotFoundError__init__(self, msg, name=None):
67-
self.msg = msg
68-
self.name = name
69-
70-
ModuleNotFoundError.__init__ = ModuleNotFoundError__init__
71-
del ModuleNotFoundError__init__
72-
73-
def ModuleNotFoundError__str__(self):
74-
if self.name is not None:
75-
return "ModuleNotFound: '" + self.name + "'. " + self.msg
76-
else:
77-
return "ModuleNotFound: " + self.msg
78-
79-
ModuleNotFoundError__str__.__init__ = ModuleNotFoundError__str__
80-
del ModuleNotFoundError__str__
81-
8266
# EnvironmentError is just an alias of OSError (i.e. 'EnvironmentError is OSError == True')
8367
EnvironmentError = OSError
8468

mx.graalpython/mx_graalpython_bench_param.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@
8989
'mmap-anonymous-sized': ITER_10 + ['20_000'],
9090
'mmap-file': ITER_10 + ['1000'],
9191
'generate-functions-sized': ITER_15 + ['500_000_000'],
92-
'try-except-sized': ITER_10 + ['100_000_000'],
9392
'try-except-simple': ITER_10 + ['500_000_000'],
94-
'try-except-store-sized': ITER_10 + ['100_000_000'],
9593
'try-except-store-simple': ITER_10 + ['500_000_000'],
9694
'try-except-store-two-types': ITER_10 + ['100_000_000'],
9795
'try-except-two-types': ITER_10 + ['100_000_000'],

mx.graalpython/suite.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,6 @@
136136
"source": [],
137137
},
138138

139-
"perf.benchmarks": {
140-
"type": "python",
141-
"path": 'graalpython/com.oracle.graal.python.benchmarks',
142-
"source": [
143-
"python"
144-
],
145-
},
146-
147139
"util.scripts": {
148140
"type": "python",
149141
"path": 'scripts',

0 commit comments

Comments
 (0)