Kaydet (Commit) 8b777670 authored tarafından Jack Jansen's avatar Jack Jansen

Donovan Preston's patch #538395, with some mods by me.

This patch makes inheritance for OSA classes work. The implementation is a
bit convoluted, but I don't immedeately see a simpler way of doing it.

I added calls to ascii() everywhere we output strings that may contain
non-ascii characters (Python has gotten very picky since the encoding
patch:-).

I also removed Donovan's different way of opening resource files: I don't
seem to need it.
üst b2bb8730
...@@ -24,6 +24,7 @@ import macfs ...@@ -24,6 +24,7 @@ import macfs
import StringIO import StringIO
import aetypes import aetypes
from aetypes import mkenum, mktype from aetypes import mkenum, mktype
import os
# These ones seem to be missing from AppleEvents # These ones seem to be missing from AppleEvents
# (they're in AERegistry.h) # (they're in AERegistry.h)
...@@ -61,6 +62,15 @@ AEDescType = AE.AEDescType ...@@ -61,6 +62,15 @@ AEDescType = AE.AEDescType
FSSType = macfs.FSSpecType FSSType = macfs.FSSpecType
AliasType = macfs.AliasType AliasType = macfs.AliasType
def packkey(ae, key, value):
if hasattr(key, 'which'):
keystr = key.which
elif hasattr(key, 'want'):
keystr = key.want
else:
keystr = key
ae.AEPutParamDesc(keystr, pack(value))
def pack(x, forcetype = None): def pack(x, forcetype = None):
"""Pack a python object into an AE descriptor""" """Pack a python object into an AE descriptor"""
...@@ -99,13 +109,18 @@ def pack(x, forcetype = None): ...@@ -99,13 +109,18 @@ def pack(x, forcetype = None):
if t == DictionaryType: if t == DictionaryType:
record = AE.AECreateList('', 1) record = AE.AECreateList('', 1)
for key, value in x.items(): for key, value in x.items():
record.AEPutParamDesc(key, pack(value)) packkey(record, key, value)
#record.AEPutParamDesc(key, pack(value))
return record return record
if t == InstanceType and hasattr(x, '__aepack__'): if t == InstanceType and hasattr(x, '__aepack__'):
return x.__aepack__() return x.__aepack__()
if hasattr(x, 'which'):
return AE.AECreateDesc('TEXT', x.which)
if hasattr(x, 'want'):
return AE.AECreateDesc('TEXT', x.want)
return AE.AECreateDesc('TEXT', repr(x)) # Copout return AE.AECreateDesc('TEXT', repr(x)) # Copout
def unpack(desc): def unpack(desc, formodulename=""):
"""Unpack an AE descriptor to a python object""" """Unpack an AE descriptor to a python object"""
t = desc.type t = desc.type
...@@ -117,17 +132,17 @@ def unpack(desc): ...@@ -117,17 +132,17 @@ def unpack(desc):
l = [] l = []
for i in range(desc.AECountItems()): for i in range(desc.AECountItems()):
keyword, item = desc.AEGetNthDesc(i+1, '****') keyword, item = desc.AEGetNthDesc(i+1, '****')
l.append(unpack(item)) l.append(unpack(item, formodulename))
return l return l
if t == typeAERecord: if t == typeAERecord:
d = {} d = {}
for i in range(desc.AECountItems()): for i in range(desc.AECountItems()):
keyword, item = desc.AEGetNthDesc(i+1, '****') keyword, item = desc.AEGetNthDesc(i+1, '****')
d[keyword] = unpack(item) d[keyword] = unpack(item, formodulename)
return d return d
if t == typeAEText: if t == typeAEText:
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc('reco')
return mkaetext(unpack(record)) return mkaetext(unpack(record, formodulename))
if t == typeAlias: if t == typeAlias:
return macfs.RawAlias(desc.data) return macfs.RawAlias(desc.data)
# typeAppleEvent returned as unknown # typeAppleEvent returned as unknown
...@@ -153,7 +168,7 @@ def unpack(desc): ...@@ -153,7 +168,7 @@ def unpack(desc):
return macfs.RawFSSpec(desc.data) return macfs.RawFSSpec(desc.data)
if t == typeInsertionLoc: if t == typeInsertionLoc:
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc('reco')
return mkinsertionloc(unpack(record)) return mkinsertionloc(unpack(record, formodulename))
# typeInteger equal to typeLongInteger # typeInteger equal to typeLongInteger
if t == typeIntlText: if t == typeIntlText:
script, language = struct.unpack('hh', desc.data[:4]) script, language = struct.unpack('hh', desc.data[:4])
...@@ -177,7 +192,11 @@ def unpack(desc): ...@@ -177,7 +192,11 @@ def unpack(desc):
return v return v
if t == typeObjectSpecifier: if t == typeObjectSpecifier:
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc('reco')
return mkobject(unpack(record)) # If we have been told the name of the module we are unpacking aedescs for,
# we can attempt to create the right type of python object from that module.
if formodulename:
return mkobjectfrommodule(unpack(record, formodulename), formodulename)
return mkobject(unpack(record, formodulename))
# typePict returned as unknown # typePict returned as unknown
# typePixelMap coerced to typeAERecord # typePixelMap coerced to typeAERecord
# typePixelMapMinus returned as unknown # typePixelMapMinus returned as unknown
...@@ -214,13 +233,13 @@ def unpack(desc): ...@@ -214,13 +233,13 @@ def unpack(desc):
# #
if t == 'rang': if t == 'rang':
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc('reco')
return mkrange(unpack(record)) return mkrange(unpack(record, formodulename))
if t == 'cmpd': if t == 'cmpd':
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc('reco')
return mkcomparison(unpack(record)) return mkcomparison(unpack(record, formodulename))
if t == 'logi': if t == 'logi':
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc('reco')
return mklogical(unpack(record)) return mklogical(unpack(record, formodulename))
return mkunknown(desc.type, desc.data) return mkunknown(desc.type, desc.data)
def coerce(data, egdata): def coerce(data, egdata):
...@@ -311,6 +330,20 @@ def mkobject(dict): ...@@ -311,6 +330,20 @@ def mkobject(dict):
return aetypes.Property(seld.type, fr) return aetypes.Property(seld.type, fr)
return aetypes.ObjectSpecifier(want, form, seld, fr) return aetypes.ObjectSpecifier(want, form, seld, fr)
# Note by Jack: I'm not 100% sure of the following code. This was
# provided by Donovan Preston, but I wonder whether the assignment
# to __class__ is safe. Moreover, shouldn't there be a better
# initializer for the classes in the suites?
def mkobjectfrommodule(dict, modulename):
want = dict['want'].type
module = __import__(modulename)
codenamemapper = module._classdeclarations
classtype = codenamemapper.get(want, None)
newobj = mkobject(dict)
if classtype:
newobj.__class__ = classtype
return newobj
def _test(): def _test():
"""Test program. Pack and unpack various things""" """Test program. Pack and unpack various things"""
objs = [ objs = [
......
...@@ -28,7 +28,7 @@ import MacOS ...@@ -28,7 +28,7 @@ import MacOS
import sys import sys
from aetypes import * from aetypes import *
from aepack import pack, unpack, coerce, AEDescType from aepack import packkey, pack, unpack, coerce, AEDescType
Error = 'aetools.Error' Error = 'aetools.Error'
...@@ -56,19 +56,19 @@ def missed(ae): ...@@ -56,19 +56,19 @@ def missed(ae):
return None return None
return desc.data return desc.data
def unpackevent(ae): def unpackevent(ae, formodulename=""):
parameters = {} parameters = {}
try: try:
dirobj = ae.AEGetParamDesc('----', '****') dirobj = ae.AEGetParamDesc('----', '****')
except AE.Error: except AE.Error:
pass pass
else: else:
parameters['----'] = unpack(dirobj) parameters['----'] = unpack(dirobj, formodulename)
del dirobj del dirobj
while 1: while 1:
key = missed(ae) key = missed(ae)
if not key: break if not key: break
parameters[key] = unpack(ae.AEGetParamDesc(key, '****')) parameters[key] = unpack(ae.AEGetParamDesc(key, '****'), formodulename)
attributes = {} attributes = {}
for key in aekeywords: for key in aekeywords:
try: try:
...@@ -77,14 +77,14 @@ def unpackevent(ae): ...@@ -77,14 +77,14 @@ def unpackevent(ae):
if msg[0] != -1701 and msg[0] != -1704: if msg[0] != -1701 and msg[0] != -1704:
raise sys.exc_type, sys.exc_value raise sys.exc_type, sys.exc_value
continue continue
attributes[key] = unpack(desc) attributes[key] = unpack(desc, formodulename)
return parameters, attributes return parameters, attributes
def packevent(ae, parameters = {}, attributes = {}): def packevent(ae, parameters = {}, attributes = {}):
for key, value in parameters.items(): for key, value in parameters.items():
ae.AEPutParamDesc(key, pack(value)) packkey(ae, key, value)
for key, value in attributes.items(): for key, value in attributes.items():
ae.AEPutAttributeDesc(key, pack(value)) packkey(ae, key, value)
# #
# Support routine for automatically generated Suite interfaces # Support routine for automatically generated Suite interfaces
...@@ -130,6 +130,7 @@ def decodeerror(arguments): ...@@ -130,6 +130,7 @@ def decodeerror(arguments):
class TalkTo: class TalkTo:
"""An AE connection to an application""" """An AE connection to an application"""
_signature = None # Can be overridden by subclasses _signature = None # Can be overridden by subclasses
_moduleName = None # Can be overridden by subclasses
def __init__(self, signature=None, start=0, timeout=0): def __init__(self, signature=None, start=0, timeout=0):
"""Create a communication channel with a particular application. """Create a communication channel with a particular application.
...@@ -183,7 +184,7 @@ class TalkTo: ...@@ -183,7 +184,7 @@ class TalkTo:
reply = event.AESend(self.send_flags, self.send_priority, reply = event.AESend(self.send_flags, self.send_priority,
self.send_timeout) self.send_timeout)
parameters, attributes = unpackevent(reply) parameters, attributes = unpackevent(reply, self._moduleName)
return reply, parameters, attributes return reply, parameters, attributes
def send(self, code, subcode, parameters = {}, attributes = {}): def send(self, code, subcode, parameters = {}, attributes = {}):
...@@ -218,6 +219,29 @@ class TalkTo: ...@@ -218,6 +219,29 @@ class TalkTo:
if _arguments.has_key('----'): if _arguments.has_key('----'):
return _arguments['----'] return _arguments['----']
if as:
item.__class__ = as
return item
def _set(self, _object, _arguments = {}, _attributes = {}):
""" _set: set data for an object
Required argument: the object
Keyword argument _parameters: Parameter dictionary for the set operation
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: the data
"""
_code = 'core'
_subcode = 'setd'
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise Error, decodeerror(_arguments)
if _arguments.has_key('----'):
return _arguments['----']
# Tiny Finder class, for local use only # Tiny Finder class, for local use only
......
...@@ -9,9 +9,9 @@ import string ...@@ -9,9 +9,9 @@ import string
# convoluted, since there are cyclic dependencies between this file and # convoluted, since there are cyclic dependencies between this file and
# aetools_convert. # aetools_convert.
# #
def pack(*args): def pack(*args, **kwargs):
from aepack import pack from aepack import pack
return apply(pack, args) return apply(pack, args, kwargs)
def IsSubclass(cls, base): def IsSubclass(cls, base):
"""Test whether CLASS1 is the same as or a subclass of CLASS2""" """Test whether CLASS1 is the same as or a subclass of CLASS2"""
...@@ -69,6 +69,26 @@ def mkenum(enum): ...@@ -69,6 +69,26 @@ def mkenum(enum):
if IsEnum(enum): return enum if IsEnum(enum): return enum
return Enum(enum) return Enum(enum)
# Jack changed the way this is done
class InsertionLoc:
def __init__(self, of, pos):
self.of = of
self.pos = pos
def __repr__(self):
return "InsertionLoc(%s, %s)" % (`self.of`, `self.pos`)
def __aepack__(self):
rec = {'kobj': self.of, 'kpos': self.pos}
return pack(rec, forcetype='insl')
# Convenience functions for dsp:
def beginning(of):
return InsertionLoc(of, Enum('bgng'))
def end(of):
return InsertionLoc(of, Enum('end '))
class Boolean: class Boolean:
"""An AE boolean value""" """An AE boolean value"""
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment