summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2018-05-16 19:04:57 (GMT)
committerGitHub <noreply@github.com>2018-05-16 19:04:57 (GMT)
commit6d2cd9036c0ab78a83de43d1511befb7a7fc0ade (patch)
tree44b1a52ab32b914553b17196f4b6b75fdbf03d06 /Python
parent55e53c309359327e54eb74b101c5a3240ea9cd45 (diff)
downloadcpython-6d2cd9036c0ab78a83de43d1511befb7a7fc0ade.zip
cpython-6d2cd9036c0ab78a83de43d1511befb7a7fc0ade.tar.gz
cpython-6d2cd9036c0ab78a83de43d1511befb7a7fc0ade.tar.bz2
bpo-32604: Improve subinterpreter tests. (#6914)
Add more tests for subinterpreters. This patch also fixes a few small defects in the channel implementation.
Diffstat (limited to 'Python')
-rw-r--r--Python/pystate.c80
1 files changed, 77 insertions, 3 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index 140d2fb..d276bfc 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1308,6 +1308,10 @@ _PyCrossInterpreterData_Register_Class(PyTypeObject *cls,
return res;
}
+/* Cross-interpreter objects are looked up by exact match on the class.
+ We can reassess this policy when we move from a global registry to a
+ tp_* slot. */
+
crossinterpdatafunc
_PyCrossInterpreterData_Lookup(PyObject *obj)
{
@@ -1332,19 +1336,79 @@ _PyCrossInterpreterData_Lookup(PyObject *obj)
/* cross-interpreter data for builtin types */
+struct _shared_bytes_data {
+ char *bytes;
+ Py_ssize_t len;
+};
+
static PyObject *
_new_bytes_object(_PyCrossInterpreterData *data)
{
- return PyBytes_FromString((char *)(data->data));
+ struct _shared_bytes_data *shared = (struct _shared_bytes_data *)(data->data);
+ return PyBytes_FromStringAndSize(shared->bytes, shared->len);
}
static int
_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data)
{
- data->data = (void *)(PyBytes_AS_STRING(obj));
+ struct _shared_bytes_data *shared = PyMem_NEW(struct _shared_bytes_data, 1);
+ if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) {
+ return -1;
+ }
+ data->data = (void *)shared;
data->obj = obj; // Will be "released" (decref'ed) when data released.
data->new_object = _new_bytes_object;
- data->free = NULL; // Do not free the data (it belongs to the object).
+ data->free = PyMem_Free;
+ return 0;
+}
+
+struct _shared_str_data {
+ int kind;
+ const void *buffer;
+ Py_ssize_t len;
+};
+
+static PyObject *
+_new_str_object(_PyCrossInterpreterData *data)
+{
+ struct _shared_str_data *shared = (struct _shared_str_data *)(data->data);
+ return PyUnicode_FromKindAndData(shared->kind, shared->buffer, shared->len);
+}
+
+static int
+_str_shared(PyObject *obj, _PyCrossInterpreterData *data)
+{
+ struct _shared_str_data *shared = PyMem_NEW(struct _shared_str_data, 1);
+ shared->kind = PyUnicode_KIND(obj);
+ shared->buffer = PyUnicode_DATA(obj);
+ shared->len = PyUnicode_GET_LENGTH(obj) - 1;
+ data->data = (void *)shared;
+ data->obj = obj; // Will be "released" (decref'ed) when data released.
+ data->new_object = _new_str_object;
+ data->free = PyMem_Free;
+ return 0;
+}
+
+static PyObject *
+_new_long_object(_PyCrossInterpreterData *data)
+{
+ return PyLong_FromLongLong((int64_t)(data->data));
+}
+
+static int
+_long_shared(PyObject *obj, _PyCrossInterpreterData *data)
+{
+ int64_t value = PyLong_AsLongLong(obj);
+ if (value == -1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ PyErr_SetString(PyExc_OverflowError, "try sending as bytes");
+ }
+ return -1;
+ }
+ data->data = (void *)value;
+ data->obj = NULL;
+ data->new_object = _new_long_object;
+ data->free = NULL;
return 0;
}
@@ -1374,10 +1438,20 @@ _register_builtins_for_crossinterpreter_data(void)
Py_FatalError("could not register None for cross-interpreter sharing");
}
+ // int
+ if (_register_xidata(&PyLong_Type, _long_shared) != 0) {
+ Py_FatalError("could not register int for cross-interpreter sharing");
+ }
+
// bytes
if (_register_xidata(&PyBytes_Type, _bytes_shared) != 0) {
Py_FatalError("could not register bytes for cross-interpreter sharing");
}
+
+ // str
+ if (_register_xidata(&PyUnicode_Type, _str_shared) != 0) {
+ Py_FatalError("could not register str for cross-interpreter sharing");
+ }
}