[Pythonmac-SIG] Re: improving appscript architecture

has hengist.podd at virgin.net
Thu Jul 15 17:43:52 CEST 2004


Jack wrote:

>>Given that I'm angling for appscript's eventual inclusion in the 
>>standard MacPython library, the code needs to be grokkable and 
>>maintainable by others (lest I be hit by the Proverbial Bus 
>>someday).
>
>I'm very interested in understanding this (as I'll probably be the 
>default maintainer if it gets included in the standard distribution) 
>but I have tried a couple of times to understand your message and I 
>simply can't seem to grok it.

Can't blame ya. I wrote that stuff in a hurry before zipping off for 
the week; I don't think I could understand it now either. :p


>Could you come up with a more concrete example of what the problem 
>is that you're trying to solve? Or, alternatively, explain the 
>architecture that you're using for appscript at the moment.

For now I'll answer the latter.

This rebuild gets rid of appscript 0.5.0's monolithic design. While 
it works, everything is dependent on everything else so it doesn't 
adapt well to multiple uses. The new architecture consists of lots of 
small, simple, loosely-coupled packages that can be combined however 
you like. The two most basic packages are:

- aecodecs -- convert Python data to/from Apple event data (i.e. this 
package is roughly equivalent to Python's aepack module, minus all 
the object specifier-related stuff which is now dealt with separately)

- AEM -- creates AEAddressDescs and sends Apple events (i.e. roughly 
equivalent to the old aetools)

I'll probably rename AEM to aesend at some point. I'll then rework 
the MiniAEFrame module to create a new package, aereceive, as a 
complement to aesend. These three packages should cover all your 
basic Apple event needs: client applications can send basic AEs using 
aecodecs and aesend; server applications would use aecodecs and 
aereceive.


The next layer consists of a single package:

- objspec -- extends aecodecs with support for object specifiers (raw 
AE codes only)

This package wraps and re-exports aecodecs, adding support for object 
specifiers as it does so. This lets you construct object specifiers 
using raw 4-letter codes. Sort of what the old aetypes module does, 
but with a superior API. Whereas aetypes provides a bunch of loose 
classes that directly represent the various AE types used to 
construct object specifiers and leaves the user to assemble them in 
the right order, objspec lets you construct references via chained 
method calls. e.g. To refer to the text property of document 1 of an 
application:

   ref = objspec.app.elems('docu').byindex(1).prop('ctxt')

Basically the same 'smart' approach used by appscript 0.5.0, but 
without the syntactic sugar and OSA terminology support. This API may 
be used directly by Python application developers who want to 
manipulate object specifiers without the extra overhead of working 
with aetes. This is the package I want to make easily extensible so 
other packages can merge additional functionality like syntax sugar 
and sanity checking to give application scripters the full 'appscript 
experience', or automatic name-attribute bindings and other hooks to 
help developers writing Python-based applications to implement 
scriptability.


Other stuff I'm working on:

- osaterms -- the new aete parser (now provides a more flexible 
SAX-style API), plus some useful tools that use this parser (a basic 
aete-to-documentation renderer, and a simple code generator for 
converting application terminology into Carbon.AppleEvents-like 
contstants modules)

- aslite -- 'appscript lite' - extends objspec to allow object 
specifiers to be constructed using application terminology obtained 
via osaterms


The aslite package is mostly just a testbed for seeing how objspec is 
panning out extensibility-wise. (Answer: not very well so far.) What 
I'd really like to be able to do is duplicate the entire objspec 
module, then insert the new behaviours directly into the duplicate's 
classes. (Prototype-based OO languages make this kind of powerful 
object extension dead easy, which is why I get a bit frustrated at 
class-based OO languages which are simultaneously more complex and 
less flexible.)


>The nice side of the old gensuitemodule architecture was that it was 
>nicely compartmentalized, so you could really understand it a bit at 
>a time: the C-stuff is completely self-contained, as is aepack. 
>Aetypes had a bit more complexity, but it was all basically 
>localized. Gensuitemodule is standalone, and the two-pass 
>architecture made it also reasonably easy to understand.

Yeah, the new appscript architecture is meant to provide the same 
kind of compartmentalisation, eliminating heavy coupling, circular 
references, etc. that prevent the old appscript's constituent parts 
being useful/understandable/testable outside of the complete package. 
(Actually, I think even the old gsm architecture is more tightly 
bound together than the new appscript.)


>And the generated packages had (at the price of being incorrect:-) 
>also only limited global complexity (the name lookups being the main 
>one), with only limited dependency on magic implemented by aetypes.

appscript did away with glues completely. There's really no value in 
creating proxy classes based on an application's aete: it's just a 
way of sugaring the API used to construct object specifiers so it 
looks like familiar conventional OO references rather than exotic 
queries, and Python lets you achieve that via __getattr__. (I believe 
there's other Python-to-X bridges that use the same basic technique 
to dress up their query-based interfaces.)

The downside of sugar is it obscures mechanics, which is a nuisance 
for someone like yourself trying to figure out how the implementation 
works (this is just as true of glues, which obscure the query-centric 
nature of object specifiers). Objspec implements the query-building 
API sans sugar, so should be reasonably easy to follow once you map 
out the inheritance hierarchy used to compose specifier behaviours.


Hope that explains the basic architecture; if it has, we can start 
discussing the objspec extensibility problem. Let me know.

has
-- 
http://freespace.virgin.net/hamish.sanderson/


More information about the Pythonmac-SIG mailing list