import pickle
import locale
import sys
+import textwrap
import types
import unittest.mock
import weakref
)
+class SubinterpreterTests(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ global interpreters
+ try:
+ from test.support import interpreters
+ except ModuleNotFoundError:
+ raise unittest.SkipTest('subinterpreters required')
+ import test.support.interpreters.channels
+
+ @cpython_only
+ def test_slot_wrappers(self):
+ rch, sch = interpreters.channels.create()
+
+ # For now it's sufficient to check int.__str__.
+ # See https://github.com/python/cpython/issues/117482
+ # and https://github.com/python/cpython/pull/117660.
+ script = textwrap.dedent('''
+ text = repr(int.__str__)
+ sch.send_nowait(text)
+ ''')
+
+ exec(script)
+ expected = rch.recv()
+
+ interp = interpreters.create()
+ interp.exec('from test.support import interpreters')
+ interp.prepare_main(sch=sch)
+ interp.exec(script)
+ results = rch.recv()
+
+ self.assertEqual(results, expected)
+
+
if __name__ == '__main__':
unittest.main()
}
}
+static PyTypeObject *
+managed_static_type_get_def(PyTypeObject *self, int isbuiltin)
+{
+ size_t index = managed_static_type_index_get(self);
+ size_t full_index = isbuiltin
+ ? index
+ : index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES;
+ return &_PyRuntime.types.managed_static.types[full_index].def;
+}
+
// Also see _PyStaticType_InitBuiltin() and _PyStaticType_FiniBuiltin().
/* end static builtin helpers */
_PyStaticType_ClearWeakRefs(interp, type);
managed_static_type_state_clear(interp, type, isbuiltin, final);
- /* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
}
void
return 0;
}
-static int add_operators(PyTypeObject *);
+static int add_operators(PyTypeObject *, PyTypeObject *);
static int add_tp_new_wrapper(PyTypeObject *type);
#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
static int
-type_ready_fill_dict(PyTypeObject *type)
+type_ready_fill_dict(PyTypeObject *type, PyTypeObject *def)
{
/* Add type-specific descriptors to tp_dict */
- if (add_operators(type) < 0) {
+ if (add_operators(type, def) < 0) {
return -1;
}
if (type_add_methods(type) < 0) {
static int
-type_ready(PyTypeObject *type, int initial)
+type_ready(PyTypeObject *type, PyTypeObject *def, int initial)
{
ASSERT_TYPE_LOCK_HELD();
if (type_ready_set_new(type, initial) < 0) {
goto error;
}
- if (type_ready_fill_dict(type) < 0) {
+ if (type_ready_fill_dict(type, def) < 0) {
goto error;
}
if (initial) {
int res;
BEGIN_TYPE_LOCK();
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
- res = type_ready(type, 1);
+ res = type_ready(type, NULL, 1);
} else {
res = 0;
assert(_PyType_CheckConsistency(type));
managed_static_type_state_init(interp, self, isbuiltin, initial);
+ PyTypeObject *def = managed_static_type_get_def(self, isbuiltin);
+ if (initial) {
+ memcpy(def, self, sizeof(PyTypeObject));
+ }
+
int res;
BEGIN_TYPE_LOCK();
- res = type_ready(self, initial);
+ res = type_ready(self, def, initial);
END_TYPE_LOCK();
if (res < 0) {
_PyStaticType_ClearWeakRefs(interp, self);
managed_static_type_state_clear(interp, self, isbuiltin, initial);
}
+
return res;
}
infinite recursion here.) */
static int
-add_operators(PyTypeObject *type)
+add_operators(PyTypeObject *type, PyTypeObject *def)
{
PyObject *dict = lookup_tp_dict(type);
pytype_slotdef *p;
PyObject *descr;
void **ptr;
+ assert(def == NULL || (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
+ if (def == NULL) {
+ def = type;
+ }
+
for (p = slotdefs; p->name; p++) {
if (p->wrapper == NULL)
continue;
- ptr = slotptr(type, p->offset);
+ ptr = slotptr(def, p->offset);
if (!ptr || !*ptr)
continue;
int r = PyDict_Contains(dict, p->name_strobj);