Skip to content

Commit dfff3e3

Browse files
_interpreters.RunFailedError -> interpreters.RunFailedError
1 parent 61845dd commit dfff3e3

File tree

4 files changed

+28
-67
lines changed

4 files changed

+28
-67
lines changed

Lib/test/support/interpreters.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,27 @@
1414

1515
__all__ = [
1616
'Interpreter', 'get_current', 'get_main', 'create', 'list_all',
17+
'RunFailedError',
1718
'SendChannel', 'RecvChannel',
1819
'create_channel', 'list_all_channels', 'is_shareable',
1920
'ChannelError', 'ChannelNotFoundError',
2021
'ChannelEmptyError',
2122
]
2223

2324

25+
class RunFailedError(RuntimeError):
26+
27+
def __init__(self, excinfo):
28+
msg = excinfo.formatted
29+
if not msg:
30+
if excinfo.type and snapshot.msg:
31+
msg = f'{snapshot.type.__name__}: {snapshot.msg}'
32+
else:
33+
msg = snapshot.type.__name__ or snapshot.msg
34+
super().__init__(msg)
35+
self.snapshot = excinfo
36+
37+
2438
def create(*, isolated=True):
2539
"""Return a new (idle) Python interpreter."""
2640
id = _interpreters.create(isolated=isolated)
@@ -110,11 +124,9 @@ def run(self, src_str, /, channels=None):
110124
that time, the previous interpreter is allowed to run
111125
in other threads.
112126
"""
113-
err = _interpreters.exec(self._id, src_str, channels)
114-
if err is not None:
115-
exc = RunFailedError(err.formatted)
116-
exc.snapshot = err
117-
raise exc
127+
excinfo = _interpreters.exec(self._id, src_str, channels)
128+
if excinfo is not None:
129+
raise RunFailedError(excinfo)
118130

119131

120132
def create_channel():

Lib/test/test__xxsubinterpreters.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,6 @@ def add_module(self, modname, text):
940940
return script_helper.make_script(tempdir, modname, text)
941941

942942
def run_script(self, text, *, fails=False):
943-
excwrapper = interpreters.RunFailedError
944943
r, w = os.pipe()
945944
try:
946945
script = dedent(f"""
@@ -980,18 +979,18 @@ def _assert_run_failed(self, exctype, msg, script):
980979
exctype_name = exctype.__name__
981980

982981
# Run the script.
983-
exc = self.run_script(script, fails=True)
982+
excinfo = self.run_script(script, fails=True)
984983

985984
# Check the wrapper exception.
986-
self.assertEqual(exc.type.__name__, exctype_name)
985+
self.assertEqual(excinfo.type.__name__, exctype_name)
987986
if msg is None:
988-
self.assertEqual(exc.formatted.split(':')[0],
987+
self.assertEqual(excinfo.formatted.split(':')[0],
989988
exctype_name)
990989
else:
991-
self.assertEqual(exc.formatted,
990+
self.assertEqual(excinfo.formatted,
992991
'{}: {}'.format(exctype_name, msg))
993992

994-
return exc
993+
return excinfo
995994

996995
def assert_run_failed(self, exctype, script):
997996
self._assert_run_failed(exctype, None, script)

Lib/test/test_interpreters.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,11 @@ def test_success(self):
478478

479479
self.assertEqual(out, 'it worked!')
480480

481+
def test_failure(self):
482+
interp = interpreters.create()
483+
with self.assertRaises(interpreters.RunFailedError):
484+
interp.run('raise Exception')
485+
481486
def test_in_thread(self):
482487
interp = interpreters.create()
483488
script, file = _captured_script('print("it worked!", end="")')

Modules/_xxsubinterpretersmodule.c

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,11 @@ _get_current_interp(void)
2828
return PyInterpreterState_Get();
2929
}
3030

31-
static PyObject *
32-
add_new_exception(PyObject *mod, const char *name, PyObject *base)
33-
{
34-
assert(!PyObject_HasAttrStringWithError(mod, name));
35-
PyObject *exctype = PyErr_NewException(name, base, NULL);
36-
if (exctype == NULL) {
37-
return NULL;
38-
}
39-
int res = PyModule_AddType(mod, (PyTypeObject *)exctype);
40-
if (res < 0) {
41-
Py_DECREF(exctype);
42-
return NULL;
43-
}
44-
return exctype;
45-
}
46-
47-
#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \
48-
add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE)
49-
5031

5132
/* module state *************************************************************/
5233

5334
typedef struct {
54-
/* exceptions */
55-
PyObject *RunFailedError;
35+
int _notused;
5636
} module_state;
5737

5838
static inline module_state *
@@ -67,18 +47,12 @@ get_module_state(PyObject *mod)
6747
static int
6848
traverse_module_state(module_state *state, visitproc visit, void *arg)
6949
{
70-
/* exceptions */
71-
Py_VISIT(state->RunFailedError);
72-
7350
return 0;
7451
}
7552

7653
static int
7754
clear_module_state(module_state *state)
7855
{
79-
/* exceptions */
80-
Py_CLEAR(state->RunFailedError);
81-
8256
return 0;
8357
}
8458

@@ -177,30 +151,6 @@ get_code_str(PyObject *arg, Py_ssize_t *len_p, PyObject **bytes_p, int *flags_p)
177151

178152
/* interpreter-specific code ************************************************/
179153

180-
static int
181-
exceptions_init(PyObject *mod)
182-
{
183-
module_state *state = get_module_state(mod);
184-
if (state == NULL) {
185-
return -1;
186-
}
187-
188-
#define ADD(NAME, BASE) \
189-
do { \
190-
assert(state->NAME == NULL); \
191-
state->NAME = ADD_NEW_EXCEPTION(mod, NAME, BASE); \
192-
if (state->NAME == NULL) { \
193-
return -1; \
194-
} \
195-
} while (0)
196-
197-
// An uncaught exception came out of interp_run_string().
198-
ADD(RunFailedError, PyExc_RuntimeError);
199-
#undef ADD
200-
201-
return 0;
202-
}
203-
204154
static int
205155
_run_script(PyObject *ns, const char *codestr, Py_ssize_t codestrlen, int flags)
206156
{
@@ -770,11 +720,6 @@ The 'interpreters' module provides a more convenient interface.");
770720
static int
771721
module_exec(PyObject *mod)
772722
{
773-
/* Add exception types */
774-
if (exceptions_init(mod) != 0) {
775-
goto error;
776-
}
777-
778723
// PyInterpreterID
779724
if (PyModule_AddType(mod, &PyInterpreterID_Type) < 0) {
780725
goto error;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy