Skip to content

Commit

Permalink
Refactor setattrbehavior calls (#227)
Browse files Browse the repository at this point in the history
* Refactor setattrbehavior calls

* Make sure all setattr handler results get checked
  • Loading branch information
frmdstryr authored Jan 20, 2025
1 parent 7030a07 commit 399399a
Showing 1 changed file with 22 additions and 69 deletions.
91 changes: 22 additions & 69 deletions atom/src/setattrbehavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,18 +268,7 @@ _mangled_property_handler( Member* member, CAtom* atom, PyObject* value )
cppy::ptr name( PyUnicode_FromFormat( "_set_%s", suffix ) );
if( !name )
return -1;
cppy::ptr callable( PyObject_GetAttr( pyobject_cast( atom ), name.get() ) );
if( !callable )
{
if( PyErr_ExceptionMatches( PyExc_AttributeError ) )
PyErr_SetString( PyExc_AttributeError, "can't set attribute" );
return -1;
}
cppy::ptr argsptr( PyTuple_New( 1 ) );
if( !argsptr )
return -1;
PyTuple_SET_ITEM( argsptr.get(), 0, cppy::incref( value ) );
cppy::ptr ok( PyObject_Call( callable.get(), argsptr.get(), 0 ) );
cppy::ptr ok( PyObject_CallMethodOneArg( pyobject_cast( atom ), name.get(), value ) );
if( !ok )
return -1;
return 0;
Expand All @@ -291,12 +280,8 @@ property_handler( Member* member, CAtom* atom, PyObject* value )
{
if( member->setattr_context != Py_None )
{
cppy::ptr argsptr( PyTuple_New( 2 ) );
if( !argsptr )
return -1;
PyTuple_SET_ITEM( argsptr.get(), 0, cppy::incref( pyobject_cast( atom ) ) );
PyTuple_SET_ITEM( argsptr.get(), 1, cppy::incref( pyobject_cast( value ) ) );
cppy::ptr ok( PyObject_Call( member->setattr_context, argsptr.get(), 0 ) );
PyObject* args[] = { pyobject_cast( atom ), value };
cppy::ptr ok( PyObject_Vectorcall( member->setattr_context, args, 2, 0 ) );
if( !ok )
return -1;
return 0;
Expand All @@ -308,17 +293,12 @@ property_handler( Member* member, CAtom* atom, PyObject* value )
int
call_object_object_value_handler( Member* member, CAtom* atom, PyObject* value )
{
cppy::ptr valueptr( cppy::incref( value ) );
valueptr = member->full_validate( atom, Py_None, valueptr.get() );
cppy::ptr valueptr( member->full_validate( atom, Py_None, value ) );
if( !valueptr )
return -1;
cppy::ptr callable( cppy::incref( member->setattr_context ) );
cppy::ptr argsptr( PyTuple_New( 2 ) );
if( !argsptr )
return -1;
PyTuple_SET_ITEM( argsptr.get(), 0, cppy::incref( pyobject_cast( atom ) ) );
PyTuple_SET_ITEM( argsptr.get(), 1, valueptr.release() );
if( !callable.call( argsptr ) )
PyObject* args[] = { pyobject_cast( atom ), valueptr.get() };
cppy::ptr ok( PyObject_Vectorcall( member->setattr_context, args, 2, 0 ) );
if( !ok )
return -1;
return 0;
}
Expand All @@ -327,18 +307,12 @@ call_object_object_value_handler( Member* member, CAtom* atom, PyObject* value )
int
call_object_object_name_value_handler( Member* member, CAtom* atom, PyObject* value )
{
cppy::ptr valueptr( cppy::incref( value ) );
valueptr = member->full_validate( atom, Py_None, valueptr.get() );
cppy::ptr valueptr( member->full_validate( atom, Py_None, value ) );
if( !valueptr )
return -1;
cppy::ptr callable( cppy::incref( member->setattr_context ) );
cppy::ptr argsptr( PyTuple_New( 3 ) );
if( !argsptr )
return -1;
PyTuple_SET_ITEM( argsptr.get(), 0, cppy::incref( pyobject_cast( atom ) ) );
PyTuple_SET_ITEM( argsptr.get(), 1, cppy::incref( member->name ) );
PyTuple_SET_ITEM( argsptr.get(), 2, valueptr.release() );
if( !callable.call( argsptr ) )
PyObject* args[] = { pyobject_cast( atom ), member->name, valueptr.get() };
cppy::ptr ok( PyObject_Vectorcall( member->setattr_context, args, 3, 0 ) );
if( !ok )
return -1;
return 0;
}
Expand All @@ -347,18 +321,11 @@ call_object_object_name_value_handler( Member* member, CAtom* atom, PyObject* va
int
object_method_value_handler( Member* member, CAtom* atom, PyObject* value )
{
cppy::ptr valueptr( cppy::incref( value ) );
valueptr = member->full_validate( atom, Py_None, valueptr.get() );
cppy::ptr valueptr( member->full_validate( atom, Py_None, value ) );
if( !valueptr )
return -1;
cppy::ptr callable( PyObject_GetAttr( pyobject_cast( atom ), member->setattr_context ) );
if( !callable )
return -1;
cppy::ptr argsptr( PyTuple_New( 1 ) );
if( !argsptr )
return -1;
PyTuple_SET_ITEM( argsptr.get(), 0, valueptr.release() );
if( !callable.call( argsptr ) )
cppy::ptr ok( PyObject_CallMethodOneArg( pyobject_cast( atom ), member->setattr_context, valueptr.get() ) );
if ( !ok )
return -1;
return 0;
}
Expand All @@ -367,19 +334,12 @@ object_method_value_handler( Member* member, CAtom* atom, PyObject* value )
int
object_method_name_value_handler( Member* member, CAtom* atom, PyObject* value )
{
cppy::ptr valueptr( cppy::incref( value ) );
valueptr = member->full_validate( atom, Py_None, valueptr.get() );
cppy::ptr valueptr( member->full_validate( atom, Py_None, value ) );
if( !valueptr )
return -1;
cppy::ptr callable( PyObject_GetAttr( pyobject_cast( atom ), member->setattr_context ) );
if( !callable )
return -1;
cppy::ptr argsptr( PyTuple_New( 2 ) );
if( !argsptr )
return -1;
PyTuple_SET_ITEM( argsptr.get(), 0, cppy::incref( member->name ) );
PyTuple_SET_ITEM( argsptr.get(), 1, valueptr.release() );
if( !callable.call( argsptr ) )
PyObject* args[] = { pyobject_cast( atom ), member->name, valueptr.get() };
cppy::ptr ok( PyObject_VectorcallMethod( member->setattr_context, args, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, 0 ) );
if( !ok )
return -1;
return 0;
}
Expand All @@ -388,19 +348,12 @@ object_method_name_value_handler( Member* member, CAtom* atom, PyObject* value )
int
member_method_object_value_handler( Member* member, CAtom* atom, PyObject* value )
{
cppy::ptr valueptr( cppy::incref( value ) );
valueptr = member->full_validate( atom, Py_None, valueptr.get() );
cppy::ptr valueptr( member->full_validate( atom, Py_None, value ) );
if( !valueptr )
return -1;
cppy::ptr callable( PyObject_GetAttr( pyobject_cast( member ), member->setattr_context ) );
if( !callable )
return -1;
cppy::ptr argsptr( PyTuple_New( 2 ) );
if( !argsptr )
return -1;
PyTuple_SET_ITEM( argsptr.get(), 0, cppy::incref( pyobject_cast( atom ) ) );
PyTuple_SET_ITEM( argsptr.get(), 1, valueptr.release() );
if( !callable.call( argsptr ) )
PyObject* args[] = { pyobject_cast( member ), pyobject_cast( atom ), valueptr.get() };
cppy::ptr ok( PyObject_VectorcallMethod( member->setattr_context, args, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, 0 ) );
if( !ok )
return -1;
return 0;
}
Expand Down

0 comments on commit 399399a

Please sign in to comment.