Conversation
xFrednet
left a comment
There was a problem hiding this comment.
The addition itself looks good, but it doesn't set the tp_reachable for most built-in types. Once that is done it should be good to go.
Sounds good. I mostly wanted to get someone else's eyes on it, and then we can decide how broad a blast radius we want. |
Modules/_immutablemodule.c
Outdated
| static PyObject * | ||
| immutable_clear_tp_reachable(PyObject *module, PyObject *obj) | ||
| { | ||
| if (!PyType_Check(obj)) { | ||
| PyErr_SetString(PyExc_TypeError, "Expected a type"); | ||
| return NULL; | ||
| } | ||
| PyTypeObject *tp = (PyTypeObject *)obj; | ||
| tp->tp_reachable = NULL; | ||
| Py_RETURN_NONE; | ||
| } | ||
|
|
There was a problem hiding this comment.
Not sure I am happy exposing this for a test. We should find a better way to test this. I think we really need to build a C-Module that doesn't have tp_reachable, and never will.
There was a problem hiding this comment.
There are c-modules in CPython which are only used for testing. They expose C Types for testing. Would that be sufficient?
| if (co->_co_cached != NULL) { | ||
| Py_VISIT(co->_co_cached->_co_code); | ||
| Py_VISIT(co->_co_cached->_co_varnames); | ||
| Py_VISIT(co->_co_cached->_co_cellvars); | ||
| Py_VISIT(co->_co_cached->_co_freevars); | ||
| } |
There was a problem hiding this comment.
This makes me worry about write barriers on the cache. There is a lot of stuff around modifying this for NoGIL
Objects/typeobject.c
Outdated
| /* | ||
| * TODO: We should discuss this. I am a little confused about the | ||
| * correct way to do this. This gives a good level of compatibility, | ||
| * but is perhaps too much. | ||
| * |
| static int | ||
| dict_reachable(PyObject *op, visitproc visit, void *arg) |
There was a problem hiding this comment.
NIT: When I implemented this, I used a dict_visit function with a flag to indicate it the keys should be used or not:
Lines 4975 to 5025 in e6fe674
I think that's slightly cleaner than having two mostly identical visit functions, but this is a style thing and this is good to go as is.
| .tp_reachable = BaseException_reachable, | ||
| 0, /* tp_weaklistoffset */ | ||
| 0, /* tp_iter */ | ||
| 0, /* tp_iternext */ | ||
| BaseException_methods, /* tp_methods */ | ||
| BaseException_members, /* tp_members */ | ||
| BaseException_getset, /* tp_getset */ | ||
| 0, /* tp_base */ | ||
| 0, /* tp_dict */ | ||
| 0, /* tp_descr_get */ | ||
| 0, /* tp_descr_set */ | ||
| offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */ | ||
| BaseException_init, /* tp_init */ | ||
| 0, /* tp_alloc */ | ||
| BaseException_new, /* tp_new */ | ||
| .tp_vectorcall = BaseException_vectorcall, |
There was a problem hiding this comment.
This seems weird, why does the change add all of these? Shouldn't it just be
.tp_reachable = BaseException_reachable,
📚 Documentation preview 📚: https://cpython-previews--65.org.readthedocs.build/