mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 04:22:16 +00:00
Use strong reference APIs.
For the free-threaded build, it is not safe use borrowed references. Another thread could deallocate the object and cause the reference to become invalid. Replace API calls that borrow references with strong reference APIs.
This commit is contained in:
@@ -68,8 +68,16 @@ object dict_base::get(object_cref k) const
|
||||
{
|
||||
if (check_exact(this))
|
||||
{
|
||||
#ifdef Py_GIL_DISABLED
|
||||
PyObject* result;
|
||||
if (PyDict_GetItemRef(this->ptr(),k.ptr(),&result) < 0) {
|
||||
throw_error_already_set();
|
||||
}
|
||||
return object(detail::new_reference(result ? result : Py_None));
|
||||
#else
|
||||
PyObject* result = PyDict_GetItem(this->ptr(),k.ptr());
|
||||
return object(detail::borrowed_reference(result ? result : Py_None));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -135,7 +135,15 @@ namespace boost { namespace python { namespace objects {
|
||||
str name(get_qualname(py_type));
|
||||
if ( py_type->tp_flags & Py_TPFLAGS_HEAPTYPE ) {
|
||||
// Qualify the type name if it is defined in a different module.
|
||||
PyObject *type_module_name = PyDict_GetItemString(py_type->tp_dict, "__module__");
|
||||
PyObject *type_module_name;
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
if (PyDict_GetItemStringRef(py_type->tp_dict, "__module__", &type_module_name) < 0) {
|
||||
throw_error_already_set();
|
||||
}
|
||||
#else
|
||||
type_module_name = PyDict_GetItemString(py_type->tp_dict, "__module__");
|
||||
Py_XINCREF(type_module_name);
|
||||
#endif
|
||||
if (
|
||||
type_module_name
|
||||
&& PyObject_RichCompareBool(
|
||||
@@ -144,8 +152,11 @@ namespace boost { namespace python { namespace objects {
|
||||
Py_NE
|
||||
) != 0
|
||||
) {
|
||||
return str("%s.%s" % make_tuple(handle<>(borrowed(type_module_name)), name));
|
||||
str result = str("%s.%s" % make_tuple(handle<>(type_module_name), name));
|
||||
return result;
|
||||
}
|
||||
// Clean up the strong reference if we didn't use it
|
||||
Py_XDECREF(type_module_name);
|
||||
}
|
||||
return name;
|
||||
} else {
|
||||
|
||||
@@ -21,20 +21,28 @@ namespace detail
|
||||
this->m_self, const_cast<char*>(name))))
|
||||
)
|
||||
{
|
||||
PyObject* borrowed_f = 0;
|
||||
|
||||
PyObject* class_f = 0;
|
||||
|
||||
if (
|
||||
PyMethod_Check(m.get())
|
||||
&& PyMethod_GET_SELF(m.get()) == this->m_self
|
||||
&& class_object->tp_dict != 0
|
||||
)
|
||||
{
|
||||
borrowed_f = ::PyDict_GetItemString(
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
if (::PyDict_GetItemStringRef(
|
||||
class_object->tp_dict, const_cast<char*>(name), &class_f) < 0) {
|
||||
throw_error_already_set();
|
||||
}
|
||||
#else
|
||||
class_f = ::PyDict_GetItemString(
|
||||
class_object->tp_dict, const_cast<char*>(name));
|
||||
|
||||
|
||||
Py_XINCREF(class_f);
|
||||
#endif
|
||||
}
|
||||
if (borrowed_f != PyMethod_GET_FUNCTION(m.get()))
|
||||
bool is_override = (class_f != PyMethod_GET_FUNCTION(m.get()));
|
||||
Py_XDECREF(class_f);
|
||||
if (is_override)
|
||||
return override(m);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user