> Mark Hammond wrote: > > >> Is there a way that I can automatically have this happen for me, so > >> that `win32com.server.util.wrap` will automatically be > called on the > >> way out of a method? > > > > It should be possible to have your _dynamic_ method do this for you? > > Instead of returning the result item, introspect what is returned > > and if it > > is an instance with _public_methods_ etc, just explicitly > do the wrap > > yourself. > > > > Or I'm missing something... :) > > Well, thats basically what I am doing now, but these object structures > that are returned can be arbitrarily complex, with lists of objects > that contain other kinds of objects, which have lists of even more > objects. Having to walk through arbitrary object structures and look > for lists/tuples of other objects, etc. is a bit of a pain, and I am > not sure if I can really do this reliably.
You don't need to recurse deeply though. If all your objects use the same policy, the sub-objects will work automatically > > Here is a simple example: > > class Person: > _public_methods_ = [] > _public_attrs_ = [ > 'firstName', > 'lastName', > 'titles' > ] > > class Title: > _public_methods_ = [] > _public_attrs_ = [ > 'name', > 'description' > ] > > p1 = Person() > p1.firstName = 'Jonathan' > p1.lastName = 'LaCour' > > t1 = Title() > t1.name = 'Some Title' > t1.description = 'Some Description' > > p1.titles.append(t1) > > In order to return arbitrary objects from my _dynamic_ method, I have > to check and see if any of the public attributes are lists or have > their own public attributes, and then replace them with "wrapped" > versions. In the above example, your hack would be called with a Person object, which you wrap. When this person object references the 'titles' attribute, you will then have see the list of instances that you wrap. There is no need to deal with the 'titles' when wrapping the Person object - just wait for the person object to return the other instances. > from win32com.server.util import wrap, register_wrapper > > register_wrapper(Title, wrap) > register_wrapper(Person, wrap) That makes sense - but such a facility doesn't exist. It would work - but I'd be leaning towards the more explicit: class Title: _com_wrap_ = wrap _public_methods_ = [...] (although the name _com_wrap_ sucks :) This would be backwards compatible. The C code in pythoncom would check for that special attribute and call it to perform a conversion into a COM object. It might get a little complicated though with respect to object identity. Consider the Python COM objects: class Child: _com_wrap_ = wrap ... class Foo: _com_wrap_ = wrap _public_attrs_ = 'child' def __init__(self): self.child = Child() # just an instance In the above example, self.child is a standard Python instance. Each time the .child attribute is fetched, COM would do the auto-wrap thing and return an instance. However - this implies it would be a *different* COM object each time the attribute was referenced. Anyone doing equality tests etc of the object itself would always fail. In the pyxpcom world, we solved that by having the wrapper store a weak-reference to the COM object. It is something we need to consider. But in general, this is something that I've always felt should be implemented in one way or another. I don't have much time at the moment though, but would be happy to help if you wanted to investigate. Cheers, Mark _______________________________________________ Python-win32 mailing list Python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32