Content-Length: 461054 | pFad | http://github.com/python/cpython/pull/111573/commits/dfff3e30ffdf25511d472385bf804bb15f71173e

9D gh-76785: Return an "excinfo" Object From Interpreter.run() by ericsnowcurrently · Pull Request #111573 · python/cpython · GitHub
Skip to content

gh-76785: Return an "excinfo" Object From Interpreter.run() #111573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
_interpreters.RunFailedError -> interpreters.RunFailedError
  • Loading branch information
ericsnowcurrently committed Nov 23, 2023
commit dfff3e30ffdf25511d472385bf804bb15f71173e
22 changes: 17 additions & 5 deletions Lib/test/support/interpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,27 @@

__all__ = [
'Interpreter', 'get_current', 'get_main', 'create', 'list_all',
'RunFailedError',
'SendChannel', 'RecvChannel',
'create_channel', 'list_all_channels', 'is_shareable',
'ChannelError', 'ChannelNotFoundError',
'ChannelEmptyError',
]


class RunFailedError(RuntimeError):

def __init__(self, excinfo):
msg = excinfo.formatted
if not msg:
if excinfo.type and snapshot.msg:
msg = f'{snapshot.type.__name__}: {snapshot.msg}'
else:
msg = snapshot.type.__name__ or snapshot.msg
super().__init__(msg)
self.snapshot = excinfo


def create(*, isolated=True):
"""Return a new (idle) Python interpreter."""
id = _interpreters.create(isolated=isolated)
Expand Down Expand Up @@ -110,11 +124,9 @@ def run(self, src_str, /, channels=None):
that time, the previous interpreter is allowed to run
in other threads.
"""
err = _interpreters.exec(self._id, src_str, channels)
if err is not None:
exc = RunFailedError(err.formatted)
exc.snapshot = err
raise exc
excinfo = _interpreters.exec(self._id, src_str, channels)
if excinfo is not None:
raise RunFailedError(excinfo)


def create_channel():
Expand Down
11 changes: 5 additions & 6 deletions Lib/test/test__xxsubinterpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,6 @@ def add_module(self, modname, text):
return script_helper.make_script(tempdir, modname, text)

def run_script(self, text, *, fails=False):
excwrapper = interpreters.RunFailedError
r, w = os.pipe()
try:
script = dedent(f"""
Expand Down Expand Up @@ -980,18 +979,18 @@ def _assert_run_failed(self, exctype, msg, script):
exctype_name = exctype.__name__

# Run the script.
exc = self.run_script(script, fails=True)
excinfo = self.run_script(script, fails=True)

# Check the wrapper exception.
self.assertEqual(exc.type.__name__, exctype_name)
self.assertEqual(excinfo.type.__name__, exctype_name)
if msg is None:
self.assertEqual(exc.formatted.split(':')[0],
self.assertEqual(excinfo.formatted.split(':')[0],
exctype_name)
else:
self.assertEqual(exc.formatted,
self.assertEqual(excinfo.formatted,
'{}: {}'.format(exctype_name, msg))

return exc
return excinfo

def assert_run_failed(self, exctype, script):
self._assert_run_failed(exctype, None, script)
Expand Down
5 changes: 5 additions & 0 deletions Lib/test/test_interpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,11 @@ def test_success(self):

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

def test_failure(self):
interp = interpreters.create()
with self.assertRaises(interpreters.RunFailedError):
interp.run('raise Exception')

def test_in_thread(self):
interp = interpreters.create()
script, file = _captured_script('print("it worked!", end="")')
Expand Down
57 changes: 1 addition & 56 deletions Modules/_xxsubinterpretersmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,11 @@ _get_current_interp(void)
return PyInterpreterState_Get();
}

static PyObject *
add_new_exception(PyObject *mod, const char *name, PyObject *base)
{
assert(!PyObject_HasAttrStringWithError(mod, name));
PyObject *exctype = PyErr_NewException(name, base, NULL);
if (exctype == NULL) {
return NULL;
}
int res = PyModule_AddType(mod, (PyTypeObject *)exctype);
if (res < 0) {
Py_DECREF(exctype);
return NULL;
}
return exctype;
}

#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \
add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE)


/* module state *************************************************************/

typedef struct {
/* exceptions */
PyObject *RunFailedError;
int _notused;
} module_state;

static inline module_state *
Expand All @@ -67,18 +47,12 @@ get_module_state(PyObject *mod)
static int
traverse_module_state(module_state *state, visitproc visit, void *arg)
{
/* exceptions */
Py_VISIT(state->RunFailedError);

return 0;
}

static int
clear_module_state(module_state *state)
{
/* exceptions */
Py_CLEAR(state->RunFailedError);

return 0;
}

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

/* interpreter-specific code ************************************************/

static int
exceptions_init(PyObject *mod)
{
module_state *state = get_module_state(mod);
if (state == NULL) {
return -1;
}

#define ADD(NAME, BASE) \
do { \
assert(state->NAME == NULL); \
state->NAME = ADD_NEW_EXCEPTION(mod, NAME, BASE); \
if (state->NAME == NULL) { \
return -1; \
} \
} while (0)

// An uncaught exception came out of interp_run_string().
ADD(RunFailedError, PyExc_RuntimeError);
#undef ADD

return 0;
}

static int
_run_script(PyObject *ns, const char *codestr, Py_ssize_t codestrlen, int flags)
{
Expand Down Expand Up @@ -770,11 +720,6 @@ The 'interpreters' module provides a more convenient interface.");
static int
module_exec(PyObject *mod)
{
/* Add exception types */
if (exceptions_init(mod) != 0) {
goto error;
}

// PyInterpreterID
if (PyModule_AddType(mod, &PyInterpreterID_Type) < 0) {
goto error;
Expand Down








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/python/cpython/pull/111573/commits/dfff3e30ffdf25511d472385bf804bb15f71173e

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy