HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Eliminating duplication in Python native code function call dispatchers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
nativeduplicationfunctioneliminatingcallpythoncodedispatchers

Problem

I attempting to merge 3 functions into one, as they contain for the most part the same code.

Here are the original functions:

`extern "C" PyObject method_noargs_call_handler( PyObject _self_and_name_tuple, PyObject * )
{
try
{
Tuple self_and_name_tuple( _self_and_name_tuple );

PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL );
if( self_as_void == NULL )
return NULL;

ExtensionModuleBase *self = static_cast( self_as_void );

Object result( self->invoke_method_noargs( PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ) ) );

return new_reference_to( result.ptr() );
}
catch( Exception & )
{
return 0;
}
}

extern "C" PyObject method_varargs_call_handler( PyObject _self_and_name_tuple, PyObject *_args )
{
try
{
Tuple self_and_name_tuple( _self_and_name_tuple );

PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL );
if( self_as_void == NULL )
return NULL;

ExtensionModuleBase *self = static_cast( self_as_void );

Tuple args( _args );
Object result
(
self->invoke_method_varargs
(
PyCapsule_GetPointer( self_and_name_tuple[1].ptr(), NULL ),
args
)
);

return new_reference_to( result.ptr() );
}
catch( Exception & )
{
return 0;
}
}

extern "C" PyObject method_keyword_call_handler( PyObject _self_and_name_tuple, PyObject _args, PyObject _keywords )
{
try
{
Tuple self_and_name_tuple( _self_and_name_tuple );

PyObject *self_in_cobject = self_and_name_tuple[0].ptr();
void *self_as_void = PyCapsule_GetPointer( self_in_cobject, NULL );
if( self_as_void

Solution

I can't comment on the Python specifics, but regarding you question:

Instead of returning from each case, assign the reference to a variable, and return the value of the variable once, after the switch.

PyObject *result_ref;

switch ( flag ) {
    case 1:
    result_ref = new_reference_to( get_result_1().ptr() );
    break;

    case 2:
    result_ref = new_reference_to( get_result_2().ptr() );
    break;

    default:
    result_ref = nullptr;
}

return result_ref;    // Still return nullptr if flag is invalid


To further reduce code duplication, you could set an Object variable in the switch instead. Then do the new_reference_to( result.ptr() ) if the flag was valid, after the switch.

Code Snippets

PyObject *result_ref;

switch ( flag ) {
    case 1:
    result_ref = new_reference_to( get_result_1().ptr() );
    break;

    case 2:
    result_ref = new_reference_to( get_result_2().ptr() );
    break;

    default:
    result_ref = nullptr;
}

return result_ref;    // Still return nullptr if flag is invalid

Context

StackExchange Code Review Q#65124, answer score: 2

Revisions (0)

No revisions yet.