[Pythonmac-SIG] package structure for OSA interfaces

Michael J. Barber mjb@uma.pt
Tue, 22 Jan 2002 11:22:10 +0000


On Monday, January 21, 2002, at 09:01  PM, Jack Jansen wrote:

>
> On Monday, January 21, 2002, at 06:40  PM, Michael J. Barber wrote:
>
>> [where should the required events be defined?]
> There is something going on here that I don't understand, maybe someone 
> else knows more about OSA can give me a hint?
>
I don't claim any great understanding of OSA, but I'll take a stab at 
this. This is all based on how tools for AppleScript work, rather than 
how AETE resources are implemented - consider yourself warned!

> It used to be that the required events were declared in the AETE 
> resource for Required (which is also where I would expect them, reading 
> Apple's documentation). However, as of a few years ago (Mac OS 9? The 
> demise of the english dialect file?) Apple moved the declarations to 
> the Standard suite. Therefore, in the Python suites they end up in the 
> standard suite module, because after all the suite modules are 
> generated.
>
> But somehow the inheritance used by (say) Script Editor is better than 
> what the Python OSA architecture uses: whereas Python sometimes cannot 
> find open (because it's declared in Standard in stead of in Required) 
> Script Editor has no such problem.
>
I think that the main difference is that Script Editor "knows" about the 
required events. For example, consider the following simple AppleScript:
      tell application "SimpleText" to run
Works fine, of course. But SimpleText is not a scriptable app, and 
doesn't have an AETE resource. Thus, gensuitemodule just produces:
"""
Macintosh HD:Applications (Mac OS 9):SimpleText

LISTING aete+aeut RESOURCES IN 'Macintosh HD:Applications (Mac OS 
9):SimpleText'
"""
and quits. It seems like a number of scriptable apps don't bother to 
define the required events, and just rely on the default behavior 
available to all apps. Looking through my Applications folder, it 
appears that only Apple does define them.

> More serious is that if the events are defined in multiple suites we 
> may end up with the wrong one. Think of the following situation
>
> class StdSuites.Standard_Suite:
> 	def open(): ....
>
> class StdSuites.Required_Suite:
> 	def open(): .... # Same as above
>
> class MyApp.Standard_Suite(StdSuites.Standard_Suite): pass
>
> class MyApp.Required_Suite(StdSuites.Required_Suite):
> 	def open():
> 		# version of open with, say, an extra optional parameter
>
> clas MyApp(Standard_Suite, Required_Suite): pass
>
> (Phew, that was a long example:-)
> Anyway: now MyApp.open will be the wrong method: it will be the method 
> declared in StdSuites.Standard_Suite in stead of the one from 
> MyApp.Required_Suite!
>
Couldn't this already be a problem? No matter what is defined in 
StdSuites.Required_Suite, the method from StdSuites.Standard_Suite gets 
used, right? Since most apps use vanilla versions of the required events 
and define them in the Standard Suite (or simply don't define them), it 
could easily be missed for a long time. Also, I don't know of any apps 
where Standard_Suite gets imported before Required_Suite, which might 
make this very pathological.

There is a surprisingly simple solution, but unfortunately only for 
Python 2.2+. Define the required events in StdSuites.Required_Suite, 
remove the required events from StdSuites.Standard_Suite, and make 
StdSuites.Standard_Suite a subclass of StdSuites.Required_Suite. 
Everything else stays as it is. With the new "diamond rule" for multiple 
inheritance, that takes care of everything.

I'm not up to the ASCII art to show the structure. See 
<http://www.artsci.wustl.edu/~mjbarber/osaimport.png> for a diagram. (If 
I have the arrows backwards in that diagram, sorry - I know very little 
about how inheritance diagrams "should be" drawn.)

The question remains: is there a fix for Python 2.1 and earlier? I don't 
see one. The restructuring I suggested for 2.2 would fix the original 
difficulty that I had, but it leaves the problem that Jack has pointed 
out unchanged. Maybe this should just be documented for earlier 
versions, since it requires an app that defines the required events (not 
too uncommon), defines them in the Required Suite instead of Standard 
Suite (rare), and defines the Standard Suite before the Required Suite 
(very rare, possibly nonexistant).

I'll take a closer look at gensuitemodule to see if I can understand it 
well enough to make the modification I suggested above. For the next few 
weeks, that needs to be pretty low priority for me (work-related 
travel), but I'll try to find the time.