[Python-Dev] Making types behave like classes

Paul Prescod paulp@ActiveState.com
Fri, 23 Mar 2001 17:16:03 -0800


These are some half-baked ideas about getting classes and types to look
more similar. I would like to know whether they are workable or not and
so I present them to the people best equipped to tell me.

Many extension types have a __getattr__ that looks like this:

static PyObject *
Xxo_getattr(XxoObject *self, char *name)
{
	// try to do some work with known attribute names, else:

	return Py_FindMethod(Xxo_methods, (PyObject *)self, name);
}

Py_FindMethod can (despite its name) return any Python object, including
ordinary (non-function) attributes. It also has complete access to the
object's state and type through the self parameter. Here's what we do
today for __doc__:

		if (strcmp(name, "__doc__") == 0) {
			char *doc = self->ob_type->tp_doc;
			if (doc != NULL)
				return PyString_FromString(doc);
		}

Why can't we do this for all magic methods? 

	* __class__ would return for the type object
	* __add__,__len__, __call__, ... would return a method wrapper around
the appropriate slot, 	
	* __init__ might map to a no-op

I think that Py_FindMethod could even implement inheritance between
types if we wanted.

We already do this magic for __methods__ and __doc__. Why not for all of
the magic methods?

Many other types implement no getattr at all (the slot is NULL). In that
case, I think that we have carte blanche to define their getattr
behavior as instance-like as possible.

Finally there are the types with getattrs that do not dispatch to
Py_FindMethod. we can just change those over manually. Extension authors
will do the same when they realize that their types are not inheriting
the features that the other types are.

Benefits:

	* objects based on extension types would "look more like" classes to
Python programmers so there is less confusion about how they are
different

	* users could stop using the type() function to get concrete types and
instead use __class__. After a version or two, type() could be formally
deprecated in favor of isinstance and __class__.

	* we will have started some momentum towards type/class unification
which we could continue on into __setattr__ and subclassing.

-- 
Take a recipe. Leave a recipe.  
Python Cookbook!  http://www.activestate.com/pythoncookbook