mirror of https://github.com/python/cpython
gh-101524: Split Up the _xxsubinterpreters Module (gh-101526)
This is step 1 in potentially dropping all the "channel"-related code. Channels have already been removed from PEP 554. https://github.com/python/cpython/issues/101524
This commit is contained in:
parent
d4c410f0f9
commit
c67b00534a
|
@ -2,11 +2,12 @@
|
|||
|
||||
import time
|
||||
import _xxsubinterpreters as _interpreters
|
||||
import _xxinterpchannels as _channels
|
||||
|
||||
# aliases:
|
||||
from _xxsubinterpreters import (
|
||||
from _xxsubinterpreters import is_shareable
|
||||
from _xxinterpchannels import (
|
||||
ChannelError, ChannelNotFoundError, ChannelEmptyError,
|
||||
is_shareable,
|
||||
)
|
||||
|
||||
|
||||
|
@ -102,7 +103,7 @@ def create_channel():
|
|||
|
||||
The channel may be used to pass data safely between interpreters.
|
||||
"""
|
||||
cid = _interpreters.channel_create()
|
||||
cid = _channels.create()
|
||||
recv, send = RecvChannel(cid), SendChannel(cid)
|
||||
return recv, send
|
||||
|
||||
|
@ -110,14 +111,14 @@ def create_channel():
|
|||
def list_all_channels():
|
||||
"""Return a list of (recv, send) for all open channels."""
|
||||
return [(RecvChannel(cid), SendChannel(cid))
|
||||
for cid in _interpreters.channel_list_all()]
|
||||
for cid in _channels.list_all()]
|
||||
|
||||
|
||||
class _ChannelEnd:
|
||||
"""The base class for RecvChannel and SendChannel."""
|
||||
|
||||
def __init__(self, id):
|
||||
if not isinstance(id, (int, _interpreters.ChannelID)):
|
||||
if not isinstance(id, (int, _channels.ChannelID)):
|
||||
raise TypeError(f'id must be an int, got {id!r}')
|
||||
self._id = id
|
||||
|
||||
|
@ -152,10 +153,10 @@ class RecvChannel(_ChannelEnd):
|
|||
This blocks until an object has been sent, if none have been
|
||||
sent already.
|
||||
"""
|
||||
obj = _interpreters.channel_recv(self._id, _sentinel)
|
||||
obj = _channels.recv(self._id, _sentinel)
|
||||
while obj is _sentinel:
|
||||
time.sleep(_delay)
|
||||
obj = _interpreters.channel_recv(self._id, _sentinel)
|
||||
obj = _channels.recv(self._id, _sentinel)
|
||||
return obj
|
||||
|
||||
def recv_nowait(self, default=_NOT_SET):
|
||||
|
@ -166,9 +167,9 @@ class RecvChannel(_ChannelEnd):
|
|||
is the same as recv().
|
||||
"""
|
||||
if default is _NOT_SET:
|
||||
return _interpreters.channel_recv(self._id)
|
||||
return _channels.recv(self._id)
|
||||
else:
|
||||
return _interpreters.channel_recv(self._id, default)
|
||||
return _channels.recv(self._id, default)
|
||||
|
||||
|
||||
class SendChannel(_ChannelEnd):
|
||||
|
@ -179,7 +180,7 @@ class SendChannel(_ChannelEnd):
|
|||
|
||||
This blocks until the object is received.
|
||||
"""
|
||||
_interpreters.channel_send(self._id, obj)
|
||||
_channels.send(self._id, obj)
|
||||
# XXX We are missing a low-level channel_send_wait().
|
||||
# See bpo-32604 and gh-19829.
|
||||
# Until that shows up we fake it:
|
||||
|
@ -194,4 +195,4 @@ class SendChannel(_ChannelEnd):
|
|||
# XXX Note that at the moment channel_send() only ever returns
|
||||
# None. This should be fixed when channel_send_wait() is added.
|
||||
# See bpo-32604 and gh-19829.
|
||||
return _interpreters.channel_send(self._id, obj)
|
||||
return _channels.send(self._id, obj)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -8,6 +8,7 @@ import time
|
|||
from test import support
|
||||
from test.support import import_helper
|
||||
_interpreters = import_helper.import_module('_xxsubinterpreters')
|
||||
_channels = import_helper.import_module('_xxinterpchannels')
|
||||
from test.support import interpreters
|
||||
|
||||
|
||||
|
@ -533,7 +534,7 @@ class TestRecvChannelAttrs(TestBase):
|
|||
|
||||
def test_id_type(self):
|
||||
rch, _ = interpreters.create_channel()
|
||||
self.assertIsInstance(rch.id, _interpreters.ChannelID)
|
||||
self.assertIsInstance(rch.id, _channels.ChannelID)
|
||||
|
||||
def test_custom_id(self):
|
||||
rch = interpreters.RecvChannel(1)
|
||||
|
@ -558,7 +559,7 @@ class TestSendChannelAttrs(TestBase):
|
|||
|
||||
def test_id_type(self):
|
||||
_, sch = interpreters.create_channel()
|
||||
self.assertIsInstance(sch.id, _interpreters.ChannelID)
|
||||
self.assertIsInstance(sch.id, _channels.ChannelID)
|
||||
|
||||
def test_custom_id(self):
|
||||
sch = interpreters.SendChannel(1)
|
||||
|
|
|
@ -280,6 +280,7 @@ PYTHONPATH=$(COREPYTHONPATH)
|
|||
# Testing
|
||||
|
||||
#_xxsubinterpreters _xxsubinterpretersmodule.c
|
||||
#_xxinterpchannels _xxinterpchannelsmodule.c
|
||||
#_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
|
||||
#_testbuffer _testbuffer.c
|
||||
#_testinternalcapi _testinternalcapi.c
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
@MODULE__STRUCT_TRUE@_struct _struct.c
|
||||
@MODULE__TYPING_TRUE@_typing _typingmodule.c
|
||||
@MODULE__XXSUBINTERPRETERS_TRUE@_xxsubinterpreters _xxsubinterpretersmodule.c
|
||||
@MODULE__XXINTERPCHANNELS_TRUE@_xxinterpchannels _xxinterpchannelsmodule.c
|
||||
@MODULE__ZONEINFO_TRUE@_zoneinfo _zoneinfo.c
|
||||
|
||||
# needs libm
|
||||
|
|
|
@ -1639,6 +1639,58 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
return PyLong_FromLong(r);
|
||||
}
|
||||
|
||||
static void
|
||||
_xid_capsule_destructor(PyObject *capsule)
|
||||
{
|
||||
_PyCrossInterpreterData *data = \
|
||||
(_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL);
|
||||
if (data != NULL) {
|
||||
assert(_PyCrossInterpreterData_Release(data) == 0);
|
||||
PyMem_Free(data);
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
get_crossinterp_data(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *obj = NULL;
|
||||
if (!PyArg_ParseTuple(args, "O:get_crossinterp_data", &obj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_PyCrossInterpreterData *data = PyMem_NEW(_PyCrossInterpreterData, 1);
|
||||
if (data == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
if (_PyObject_GetCrossInterpreterData(obj, data) != 0) {
|
||||
PyMem_Free(data);
|
||||
return NULL;
|
||||
}
|
||||
PyObject *capsule = PyCapsule_New(data, NULL, _xid_capsule_destructor);
|
||||
if (capsule == NULL) {
|
||||
assert(_PyCrossInterpreterData_Release(data) == 0);
|
||||
PyMem_Free(data);
|
||||
}
|
||||
return capsule;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
restore_crossinterp_data(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *capsule = NULL;
|
||||
if (!PyArg_ParseTuple(args, "O:restore_crossinterp_data", &capsule)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_PyCrossInterpreterData *data = \
|
||||
(_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL);
|
||||
if (data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return _PyCrossInterpreterData_NewObject(data);
|
||||
}
|
||||
|
||||
static void
|
||||
slot_tp_del(PyObject *self)
|
||||
{
|
||||
|
@ -3306,6 +3358,8 @@ static PyMethodDef TestMethods[] = {
|
|||
{"run_in_subinterp_with_config",
|
||||
_PyCFunction_CAST(run_in_subinterp_with_config),
|
||||
METH_VARARGS | METH_KEYWORDS},
|
||||
{"get_crossinterp_data", get_crossinterp_data, METH_VARARGS},
|
||||
{"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS},
|
||||
{"with_tp_del", with_tp_del, METH_VARARGS},
|
||||
{"create_cfunction", create_cfunction, METH_NOARGS},
|
||||
{"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_VARARGS,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -37,6 +37,7 @@ extern PyObject* PyInit__weakref(void);
|
|||
/* XXX: These two should really be extracted to standalone extensions. */
|
||||
extern PyObject* PyInit_xxsubtype(void);
|
||||
extern PyObject* PyInit__xxsubinterpreters(void);
|
||||
extern PyObject* PyInit__xxinterpchannels(void);
|
||||
extern PyObject* PyInit__random(void);
|
||||
extern PyObject* PyInit_itertools(void);
|
||||
extern PyObject* PyInit__collections(void);
|
||||
|
@ -134,6 +135,7 @@ struct _inittab _PyImport_Inittab[] = {
|
|||
|
||||
{"xxsubtype", PyInit_xxsubtype},
|
||||
{"_xxsubinterpreters", PyInit__xxsubinterpreters},
|
||||
{"_xxinterpchannels", PyInit__xxinterpchannels},
|
||||
#ifdef _Py_HAVE_ZLIB
|
||||
{"zlib", PyInit_zlib},
|
||||
#endif
|
||||
|
|
|
@ -418,6 +418,7 @@
|
|||
<ClCompile Include="..\Modules\timemodule.c" />
|
||||
<ClCompile Include="..\Modules\xxsubtype.c" />
|
||||
<ClCompile Include="..\Modules\_xxsubinterpretersmodule.c" />
|
||||
<ClCompile Include="..\Modules\_xxinterpchannelsmodule.c" />
|
||||
<ClCompile Include="..\Modules\_io\fileio.c" />
|
||||
<ClCompile Include="..\Modules\_io\bytesio.c" />
|
||||
<ClCompile Include="..\Modules\_io\stringio.c" />
|
||||
|
|
|
@ -1322,6 +1322,9 @@
|
|||
<ClCompile Include="..\Modules\_xxsubinterpretersmodule.c">
|
||||
<Filter>Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Modules\_xxinterpchannelsmodule.c">
|
||||
<Filter>Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Parser\string_parser.c">
|
||||
<Filter>Parser</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -36,6 +36,7 @@ IGNORE = {
|
|||
'_testmultiphase',
|
||||
'_testsinglephase',
|
||||
'_xxsubinterpreters',
|
||||
'_xxinterpchannels',
|
||||
'_xxtestfuzz',
|
||||
'idlelib.idle_test',
|
||||
'test',
|
||||
|
|
|
@ -752,6 +752,8 @@ MODULE__MULTIPROCESSING_FALSE
|
|||
MODULE__MULTIPROCESSING_TRUE
|
||||
MODULE__ZONEINFO_FALSE
|
||||
MODULE__ZONEINFO_TRUE
|
||||
MODULE__XXINTERPCHANNELS_FALSE
|
||||
MODULE__XXINTERPCHANNELS_TRUE
|
||||
MODULE__XXSUBINTERPRETERS_FALSE
|
||||
MODULE__XXSUBINTERPRETERS_TRUE
|
||||
MODULE__TYPING_FALSE
|
||||
|
@ -25615,6 +25617,7 @@ case $ac_sys_system in #(
|
|||
py_cv_module__scproxy=n/a
|
||||
py_cv_module__tkinter=n/a
|
||||
py_cv_module__xxsubinterpreters=n/a
|
||||
py_cv_module__xxinterpchannels=n/a
|
||||
py_cv_module_grp=n/a
|
||||
py_cv_module_nis=n/a
|
||||
py_cv_module_ossaudiodev=n/a
|
||||
|
@ -26057,6 +26060,26 @@ fi
|
|||
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if test "$py_cv_module__xxinterpchannels" != "n/a"; then :
|
||||
py_cv_module__xxinterpchannels=yes
|
||||
fi
|
||||
if test "$py_cv_module__xxinterpchannels" = yes; then
|
||||
MODULE__XXINTERPCHANNELS_TRUE=
|
||||
MODULE__XXINTERPCHANNELS_FALSE='#'
|
||||
else
|
||||
MODULE__XXINTERPCHANNELS_TRUE='#'
|
||||
MODULE__XXINTERPCHANNELS_FALSE=
|
||||
fi
|
||||
|
||||
as_fn_append MODULE_BLOCK "MODULE__XXINTERPCHANNELS_STATE=$py_cv_module__xxinterpchannels$as_nl"
|
||||
if test "x$py_cv_module__xxinterpchannels" = xyes; then :
|
||||
|
||||
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
@ -28236,6 +28259,10 @@ if test -z "${MODULE__XXSUBINTERPRETERS_TRUE}" && test -z "${MODULE__XXSUBINTERP
|
|||
as_fn_error $? "conditional \"MODULE__XXSUBINTERPRETERS\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${MODULE__XXINTERPCHANNELS_TRUE}" && test -z "${MODULE__XXINTERPCHANNELS_FALSE}"; then
|
||||
as_fn_error $? "conditional \"MODULE__XXINTERPCHANNELS\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${MODULE__ZONEINFO_TRUE}" && test -z "${MODULE__ZONEINFO_FALSE}"; then
|
||||
as_fn_error $? "conditional \"MODULE__ZONEINFO\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
|
|
|
@ -7017,6 +7017,7 @@ AS_CASE([$ac_sys_system],
|
|||
[_scproxy],
|
||||
[_tkinter],
|
||||
[_xxsubinterpreters],
|
||||
[_xxinterpchannels],
|
||||
[grp],
|
||||
[nis],
|
||||
[ossaudiodev],
|
||||
|
@ -7135,6 +7136,7 @@ PY_STDLIB_MOD_SIMPLE([select])
|
|||
PY_STDLIB_MOD_SIMPLE([_struct])
|
||||
PY_STDLIB_MOD_SIMPLE([_typing])
|
||||
PY_STDLIB_MOD_SIMPLE([_xxsubinterpreters])
|
||||
PY_STDLIB_MOD_SIMPLE([_xxinterpchannels])
|
||||
PY_STDLIB_MOD_SIMPLE([_zoneinfo])
|
||||
|
||||
dnl multiprocessing modules
|
||||
|
|
Loading…
Reference in New Issue