> I was thinking of the same thing. I would like to solve it in another
> way, by introducing the operator __call__ for instances.
g> This is indeed a useful extension. I might add it sooner or later
g> -- sooner if someone contributes a working patch!
The patch I made allows any built-in type to overload the call
operator. I have not patched the instance object to make use of this
but I am sure it would be trivial to do. Since there is a macro for
creating a function that can be used to overload any binary operator,
all you need to do is add the line:
BINARY(instance_call, "__call__")
at a suitable place in Object/instance.c, then add an entry for
'instance_call' to the static instantiation of the instance type
object.
So, the patch is as follows:
The _typeobject structure has a new field called tp_call. For any
type that you would like to call, simply add a pointer to a
'binaryfunc' that does the right thing. Writing one of these for the
instance object is not even necessary (as I mentioned above).
(As I hinted in a previous message, I would like to see a new method
suite added that would hold all of the current 'standard methods'.)
In Include/object.h replace the _typeobject structure with
following:
typedef struct _typeobject {
OB_VARHEAD
char *tp_name; /* For printing */
unsigned int tp_basicsize, tp_itemsize; /* For allocation */
/* Methods to implement standard operations */
destructor tp_dealloc;
printfunc tp_print;
getattrfunc tp_getattr;
setattrfunc tp_setattr;
cmpfunc tp_compare;
reprfunc tp_repr;
/* Method suites for standard classes */
number_methods *tp_as_number;
sequence_methods *tp_as_sequence;
mapping_methods *tp_as_mapping;
/* More standard operations (at end for binary compatibility) */
hashfunc tp_hash;
binaryfunc tp_call;
#ifdef COUNT_ALLOCS
/* these must be last */
int tp_alloc;
int tp_free;
int tp_maxalloc;
struct _typeobject *tp_next;
#endif
} typeobject;
in Python/ceval.c replace call_object() with the following:
object *
call_object(func, arg)
object *func;
object *arg;
{
binaryfunc call;
if (call = func->ob_type->tp_call) {
int size = gettuplesize(arg);
if (arg) {
size = gettuplesize(arg);
if (size == 1)
arg = gettupleitem(arg, 0);
else if (size == 0)
arg = NULL;
}
return (*call)(func, arg);
}
if (is_instancemethodobject(func) || is_funcobject(func))
return call_function(func, arg);
else
return call_builtin(func, arg);
}
Now, arguably, I should have patched up all of the callable types to
make use of this new feature, rather than just add a new special case
to the call_object routine, but...
--Don