NAME ^

classes/pyproxytype.pmc - Python Proxy Type

DESCRIPTION ^

This is the type that you get when you subclass a non-PyClass (i.e., a builtin PyObject, like PyInt).

Invoking instances of this type (which is Python's way of instantiating instances) actually causes two objects to be created: one of type PyClass (the "proxy"), and one of intended class (the "real object").

The one "trick" is that the an additional parent is inserted into the inheritance hierarchy of type PyProxyClass. The sole function of PyProxyClass is to delegate of all method and attribute calls back onto the real object.

The combination of PyClass, PyProxyClass, and PyObject allows subclasses of builtins to redefine methods. This is because PyClass knows how to translate Parrot calls (like "get_string") into Python methods (like "__str__"), find_method on PyClass knows how to look up the inheritance chain, and having a PyProxyClass on the top of the chain knows how to forward such method talls to a PyObject, which in turn knows how to map Python method calls onto Parrot calls.

While this seems like a lot of work, lets consider all the cases:

  "pure" builtins (not subclassed by Python):
     * operations like indexing and addition are done at Parrot
       speeds with no lookaside to see if methods have been
       overridden.
     * explict calls to methods (such as __str__) are relatively
       rare, but are handled by an NCI method which maps between 
       Python and Parrot syntax and semantics.

  "pure" Python classes (base class is object):
     * operations like addition are relatively rare, but are
       accomplished by an NCI method which maps between Python
       and Parrot syntax and semantics.
     * explicit calls to methods directly check the set of
       properties (currently a hash) for each class.

  "mixed" classes (base class is builin - relatively rare):
     * operations like indexing and addition require a
       mapping to Python method names, an inheritance search,
       and mapping back to Parrot method names.
     * explicit calls to methods require only the ProxyClass and
       a mapping to Parrot methods.

Methods ^

void *invoke(void *next)

Create a new object and proxy. Note: invokes invoke on the object without touching any parrot registers... this enables initializers with arguments to be run.

PMC *subclass(STRING *name)

Create a subclass of the given class. Note that this merely creates a new PyType... all the interesting details that make it a subclass need to be filled in.


parrot