|
From: Phillip J. E. <pj...@te...> - 2001-07-12 20:24:43
|
Hi! I've recently embarked upon the somewhat quixotic mission of porting
selected portions of Jim Fulton's ExtensionClasses to Jython 2.1a2.
Initially, I tried to use Python metaclasses to do this, coupled with
Jython's ability to extend Java classes, to try and extend
org.python.core.PyInstance and org.python.core.PyClass. The results were
just successful enough to lead me down the killer rabbit hole for most of
the day.
I found out a few interesting things. First, it is possible to extend
PyClass from Python, but the way the metaclass hook is implemented, it has
no effect. Since an instance of your extended PyClass is an "instanceof"
PyClass, its meta-nature is ignored by Py.makeclass. Interestingly, this
means it is also impossible to write an ExtensionClass-like class object in
Java, at least if it extends PyClass.
Okay, so as a temporary workaround, I manually created instances of my
ExtensionClass, so that I could find out if things worked otherwise.
I want to implement the ExtensionClass __of__() protocol, wherein an object
retrieved from another object gets its __of__() method called, and the
return value is used in place of the original object. I discovered that
Jython's _doget() protocol is almost identical, except that it is only
applied to items retrieved from a class, not the instance
dictionary. Okay, close enough for an experiment, so I overrode _doget
like this:
class ExtensionInstance(PyInstance):
def _doget(self,container,foundIn):
if container is None:
return self
of = self.ifindclass('__of__',0)
# This works
return id(of)
# This doesn't - even if I just return self
if of is None:
return self
return of(self,container)
Strangely, if _doget returns an object like an integer or string, it
works. If _doget returns self, Jython hangs for an extended period (I
suspect building up to a stack overflow error). Hm.
Anyway, I'm not sure what I should be asking here. At this point, I'm
reasonably certain I can do what I need to directly in Java if I could
extend PyClass and still have the metaclass hook take effect. Any
suggestions would be appreciated.
|