From ab4a1988fd4347484a7928394b94e2cdf5f8f2a7 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 13 Jun 2018 08:02:39 -0600 Subject: [PATCH] bpo-33615: Re-enable subinterpreter tests. (#7552) All the subinterpreter tests were disabled in gh-7513. This commit re-enables them, but leaves one bad test disabled. The test is partly causing problems because it makes assumptions about the availability of a high-level interpreters module (see PEP 554). So I'm disabling the test until such a high-level module is available. --- Lib/test/test__xxsubinterpreters.py | 11 ++-- Modules/_xxsubinterpretersmodule.c | 82 ++++++++++++++++------------- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py index b3ed27cd804..ac76cc198ad 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -12,7 +12,6 @@ import unittest from test import support from test.support import script_helper -raise unittest.SkipTest("FIXME: bpo-33615: test crash on some CIs") interpreters = support.import_module('_xxsubinterpreters') @@ -1317,6 +1316,10 @@ class ChannelTests(TestBase): self.assertEqual(obj, b'spam') self.assertEqual(out.strip(), 'send') + # XXX For now there is no high-level channel into which the + # sent channel ID can be converted... + # Note: this test caused crashes on some buildbots (bpo-33615). + @unittest.skip('disabled until high-level channels exist') def test_run_string_arg_resolved(self): cid = interpreters.channel_create() cid = interpreters._channel_id(cid, _resolve=True) @@ -1324,10 +1327,8 @@ class ChannelTests(TestBase): out = _run_output(interp, dedent(""" import _xxsubinterpreters as _interpreters - print(chan.end) - _interpreters.channel_send(chan, b'spam') - #print(chan.id.end) - #_interpreters.channel_send(chan.id, b'spam') + print(chan.id.end) + _interpreters.channel_send(chan.id, b'spam') """), dict(chan=cid.send)) obj = interpreters.channel_recv(cid) diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 129067cbd19..ce243fe30bb 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1000,11 +1000,11 @@ _channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex) _channelref *ref = _channelref_find(channels->head, id, NULL); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %lld not found", id); + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); goto done; } if (ref->chan == NULL || !ref->chan->open) { - PyErr_Format(ChannelClosedError, "channel %lld closed", id); + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); goto done; } @@ -1064,16 +1064,16 @@ _channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, _channelref *ref = _channelref_find(channels->head, cid, NULL); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %lld not found", cid); + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", cid); goto done; } if (ref->chan == NULL) { - PyErr_Format(ChannelClosedError, "channel %lld closed", cid); + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); goto done; } else if (!force && end == CHANNEL_SEND && ref->chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %lld closed", cid); + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); goto done; } else { @@ -1082,7 +1082,7 @@ _channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, PyErr_ExceptionMatches(ChannelNotEmptyError)) { if (ref->chan->closing != NULL) { PyErr_Format(ChannelClosedError, - "channel %lld closed", cid); + "channel %" PRId64 " closed", cid); goto done; } // Mark the channel as closing and return. The channel @@ -1144,7 +1144,7 @@ _channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) _channelref *prev = NULL; _channelref *ref = _channelref_find(channels->head, id, &prev); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %lld not found", id); + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); goto done; } @@ -1164,7 +1164,7 @@ _channels_add_id_object(_channels *channels, int64_t id) _channelref *ref = _channelref_find(channels->head, id, NULL); if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %lld not found", id); + PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); goto done; } ref->objcount += 1; @@ -1328,7 +1328,7 @@ _channel_send(_channels *channels, int64_t id, PyObject *obj) // Past this point we are responsible for releasing the mutex. if (chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %lld closed", id); + PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); PyThread_release_lock(mutex); return -1; } @@ -1377,7 +1377,7 @@ _channel_recv(_channels *channels, int64_t id) PyThread_release_lock(mutex); if (data == NULL) { if (!PyErr_Occurred()) { - PyErr_Format(ChannelEmptyError, "channel %lld is empty", id); + PyErr_Format(ChannelEmptyError, "channel %" PRId64 " is empty", id); } return NULL; } @@ -1527,13 +1527,13 @@ channelid_repr(PyObject *self) channelid *cid = (channelid *)self; const char *fmt; if (cid->end == CHANNEL_SEND) { - fmt = "%s(%lld, send=True)"; + fmt = "%s(%" PRId64 ", send=True)"; } else if (cid->end == CHANNEL_RECV) { - fmt = "%s(%lld, recv=True)"; + fmt = "%s(%" PRId64 ", recv=True)"; } else { - fmt = "%s(%lld)"; + fmt = "%s(%" PRId64 ")"; } return PyUnicode_FromFormat(fmt, name, cid->id); } @@ -1542,7 +1542,7 @@ static PyObject * channelid_str(PyObject *self) { channelid *cid = (channelid *)self; - return PyUnicode_FromFormat("%lld", cid->id); + return PyUnicode_FromFormat("%" PRId64 "", cid->id); } PyObject * @@ -1652,6 +1652,32 @@ channelid_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_FALSE; } +static PyObject * +_channel_from_cid(PyObject *cid, int end) +{ + PyObject *highlevel = PyImport_ImportModule("interpreters"); + if (highlevel == NULL) { + PyErr_Clear(); + highlevel = PyImport_ImportModule("test.support.interpreters"); + if (highlevel == NULL) { + return NULL; + } + } + const char *clsname = (end == CHANNEL_RECV) ? "RecvChannel" : + "SendChannel"; + PyObject *cls = PyObject_GetAttrString(highlevel, clsname); + Py_DECREF(highlevel); + if (cls == NULL) { + return NULL; + } + PyObject *chan = PyObject_CallFunctionObjArgs(cls, cid, NULL); + Py_DECREF(cls); + if (chan == NULL) { + return NULL; + } + return chan; +} + struct _channelid_xid { int64_t id; int end; @@ -1673,31 +1699,13 @@ _channelid_from_xid(_PyCrossInterpreterData *data) } /* Try returning a high-level channel end but fall back to the ID. */ - PyObject *highlevel = PyImport_ImportModule("interpreters"); - if (highlevel == NULL) { - PyErr_Clear(); - highlevel = PyImport_ImportModule("test.support.interpreters"); - if (highlevel == NULL) { - goto error; - } - } - const char *clsname = (xid->end == CHANNEL_RECV) ? "RecvChannel" : - "SendChannel"; - PyObject *cls = PyObject_GetAttrString(highlevel, clsname); - Py_DECREF(highlevel); - if (cls == NULL) { - goto error; - } - PyObject *chan = PyObject_CallFunctionObjArgs(cls, cid, NULL); + PyObject *chan = _channel_from_cid(cid, xid->end); if (chan == NULL) { - goto error; + PyErr_Clear(); + return cid; } Py_DECREF(cid); return chan; - -error: - PyErr_Clear(); - return cid; } static int @@ -2048,14 +2056,14 @@ interpid_repr(PyObject *self) PyTypeObject *type = Py_TYPE(self); const char *name = _PyType_Name(type); interpid *id = (interpid *)self; - return PyUnicode_FromFormat("%s(%lld)", name, id->id); + return PyUnicode_FromFormat("%s(%" PRId64 ")", name, id->id); } static PyObject * interpid_str(PyObject *self) { interpid *id = (interpid *)self; - return PyUnicode_FromFormat("%lld", id->id); + return PyUnicode_FromFormat("%" PRId64 "", id->id); } PyObject *