mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 00:06:44 -04:00
interrogate: fix refcount trouble assigning PyObject* properties
In particular, this fixes accessing PythonTask.__dict__
This commit is contained in:
parent
45778b9e9f
commit
8e4add0326
@ -397,17 +397,25 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
||||
}
|
||||
|
||||
// It's not possible to assign arrays in C++, we have to copy them.
|
||||
CPPArrayType *array_type = _parameters[_first_true_parameter]._remap->get_orig_type()->as_array_type();
|
||||
bool paren_close = false;
|
||||
CPPType *param_type = _parameters[_first_true_parameter]._remap->get_orig_type();
|
||||
CPPArrayType *array_type = param_type->as_array_type();
|
||||
if (array_type != nullptr) {
|
||||
call << "std::copy(" << expr << ", " << expr << " + " << *array_type->_bounds << ", ";
|
||||
} else {
|
||||
paren_close = true;
|
||||
}
|
||||
else if (TypeManager::is_pointer_to_PyObject(param_type)) {
|
||||
call << "Dtool_Assign_PyObject(" << expr << ", ";
|
||||
paren_close = true;
|
||||
}
|
||||
else {
|
||||
call << expr << " = ";
|
||||
}
|
||||
|
||||
_parameters[_first_true_parameter]._remap->pass_parameter(call,
|
||||
get_parameter_expr(_first_true_parameter, pexprs));
|
||||
|
||||
if (array_type != nullptr) {
|
||||
if (paren_close) {
|
||||
call << ')';
|
||||
}
|
||||
|
||||
@ -772,6 +780,11 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
||||
_return_value_destructor = builder.get_destructor_for(return_meat_type);
|
||||
}
|
||||
|
||||
if (_type == T_getter && TypeManager::is_pointer_to_PyObject(return_type)) {
|
||||
_manage_reference_count = true;
|
||||
_return_value_needs_management = true;
|
||||
}
|
||||
|
||||
// Check for a special meaning by name and signature.
|
||||
size_t first_param = 0;
|
||||
if (_has_this) {
|
||||
|
@ -5979,7 +5979,11 @@ write_function_instance(ostream &out, FunctionRemap *remap,
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
||||
|
||||
return_expr = manage_return_value(out, indent_level, remap, "return_value");
|
||||
if (TypeManager::is_pointer_to_PyObject(remap->_return_type->get_orig_type())) {
|
||||
indent(out, indent_level) << "Py_XINCREF(return_value);\n";
|
||||
} else {
|
||||
return_expr = manage_return_value(out, indent_level, remap, "return_value");
|
||||
}
|
||||
return_expr = remap->_return_type->temporary_to_return(return_expr);
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,19 @@ INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, i
|
||||
Py_RETURN_RICHCOMPARE(cmpval, 0, op);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function for assigning a PyObject pointer while managing refcounts.
|
||||
*/
|
||||
ALWAYS_INLINE void
|
||||
Dtool_Assign_PyObject(PyObject *&ptr, PyObject *value) {
|
||||
PyObject *prev_value = ptr;
|
||||
if (prev_value != value) {
|
||||
Py_XINCREF(value);
|
||||
ptr = value;
|
||||
Py_XDECREF(prev_value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the enum value to a C long.
|
||||
*/
|
||||
|
@ -238,6 +238,8 @@ EXPCL_PYPANDA PyObject *_Dtool_Return(PyObject *value);
|
||||
#define Dtool_Return(value) _Dtool_Return(value)
|
||||
#endif
|
||||
|
||||
ALWAYS_INLINE void Dtool_Assign_PyObject(PyObject *&ptr, PyObject *value);
|
||||
|
||||
/**
|
||||
* Wrapper around Python 3.4's enum library, which does not have a C API.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user