SF patch# 1761465 by Jeffrey Yasskin.

Fix test_aepack and test_applesingle.
This commit is contained in:
Guido van Rossum 2007-07-27 04:41:00 +00:00
parent 67feb09d06
commit f7a94e4b44
7 changed files with 126 additions and 104 deletions

View File

@ -1,6 +1,6 @@
# Generated from 'AEDataModel.h' # Generated from 'AEDataModel.h'
def FOUR_CHAR_CODE(x): return x def FOUR_CHAR_CODE(x): return bytes(x)
typeBoolean = FOUR_CHAR_CODE('bool') typeBoolean = FOUR_CHAR_CODE('bool')
typeChar = FOUR_CHAR_CODE('TEXT') typeChar = FOUR_CHAR_CODE('TEXT')
typeSInt16 = FOUR_CHAR_CODE('shor') typeSInt16 = FOUR_CHAR_CODE('shor')

View File

@ -25,30 +25,36 @@ 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)
#typeColorTable = 'clrt' #typeColorTable = b'clrt'
#typeDrawingArea = 'cdrw' #typeDrawingArea = b'cdrw'
#typePixelMap = 'cpix' #typePixelMap = b'cpix'
#typePixelMapMinus = 'tpmm' #typePixelMapMinus = b'tpmm'
#typeRotation = 'trot' #typeRotation = b'trot'
#typeTextStyles = 'tsty' #typeTextStyles = b'tsty'
#typeStyledText = 'STXT' #typeStyledText = b'STXT'
#typeAEText = 'tTXT' #typeAEText = b'tTXT'
#typeEnumeration = 'enum' #typeEnumeration = b'enum'
def b2i(byte_string):
result = 0
for byte in byte_string:
result <<= 8
result += byte
return result
# #
# Some AE types are immedeately coerced into something # Some AE types are immedeately coerced into something
# we like better (and which is equivalent) # we like better (and which is equivalent)
# #
unpacker_coercions = { unpacker_coercions = {
typeComp : typeFloat, b2i(typeComp) : typeFloat,
typeColorTable : typeAEList, b2i(typeColorTable) : typeAEList,
typeDrawingArea : typeAERecord, b2i(typeDrawingArea) : typeAERecord,
typeFixed : typeFloat, b2i(typeFixed) : typeFloat,
typeExtended : typeFloat, b2i(typeExtended) : typeFloat,
typePixelMap : typeAERecord, b2i(typePixelMap) : typeAERecord,
typeRotation : typeAERecord, b2i(typeRotation) : typeAERecord,
typeStyledText : typeAERecord, b2i(typeStyledText) : typeAERecord,
typeTextStyles : typeAERecord, b2i(typeTextStyles) : typeAERecord,
}; };
# #
@ -72,33 +78,35 @@ def pack(x, forcetype = None):
"""Pack a python object into an AE descriptor""" """Pack a python object into an AE descriptor"""
if forcetype: if forcetype:
if isinstance(x, str): if isinstance(x, bytes):
return AE.AECreateDesc(forcetype, x) return AE.AECreateDesc(forcetype, x)
else: else:
return pack(x).AECoerceDesc(forcetype) return pack(x).AECoerceDesc(forcetype)
if x == None: if x == None:
return AE.AECreateDesc('null', '') return AE.AECreateDesc(b'null', '')
if isinstance(x, AEDescType): if isinstance(x, AEDescType):
return x return x
if isinstance(x, FSSType): if isinstance(x, FSSType):
return AE.AECreateDesc('fss ', x.data) return AE.AECreateDesc(b'fss ', x.data)
if isinstance(x, FSRefType): if isinstance(x, FSRefType):
return AE.AECreateDesc('fsrf', x.data) return AE.AECreateDesc(b'fsrf', x.data)
if isinstance(x, AliasType): if isinstance(x, AliasType):
return AE.AECreateDesc('alis', x.data) return AE.AECreateDesc(b'alis', x.data)
if isinstance(x, int): if isinstance(x, int):
return AE.AECreateDesc('long', struct.pack('l', x)) return AE.AECreateDesc(b'long', struct.pack('l', x))
if isinstance(x, float): if isinstance(x, float):
return AE.AECreateDesc('doub', struct.pack('d', x)) return AE.AECreateDesc(b'doub', struct.pack('d', x))
if isinstance(x, (bytes, str8)):
return AE.AECreateDesc(b'TEXT', x)
if isinstance(x, str): if isinstance(x, str):
return AE.AECreateDesc('TEXT', x) # See http://developer.apple.com/documentation/Carbon/Reference/Apple_Event_Manager/Reference/reference.html#//apple_ref/doc/constant_group/typeUnicodeText
if isinstance(x, unicode): # for the possible encodings.
data = x.encode('utf16') data = x.encode('utf16')
if data[:2] == '\xfe\xff': if data[:2] == '\xfe\xff':
data = data[2:] data = data[2:]
return AE.AECreateDesc('utxt', data) return AE.AECreateDesc(b'utxt', data)
if isinstance(x, list): if isinstance(x, list):
lst = AE.AECreateList('', 0) lst = AE.AECreateList('', 0)
for item in x: for item in x:
@ -112,37 +120,37 @@ def pack(x, forcetype = None):
return record return record
if isinstance(x, type) and issubclass(x, ObjectSpecifier): if isinstance(x, type) and issubclass(x, ObjectSpecifier):
# Note: we are getting a class object here, not an instance # Note: we are getting a class object here, not an instance
return AE.AECreateDesc('type', x.want) return AE.AECreateDesc(b'type', x.want)
if hasattr(x, '__aepack__'): if hasattr(x, '__aepack__'):
return x.__aepack__() return x.__aepack__()
if hasattr(x, 'which'): if hasattr(x, 'which'):
return AE.AECreateDesc('TEXT', x.which) return AE.AECreateDesc(b'TEXT', x.which)
if hasattr(x, 'want'): if hasattr(x, 'want'):
return AE.AECreateDesc('TEXT', x.want) return AE.AECreateDesc(b'TEXT', x.want)
return AE.AECreateDesc('TEXT', repr(x)) # Copout return AE.AECreateDesc(b'TEXT', repr(x)) # Copout
def unpack(desc, formodulename=""): 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
if t in unpacker_coercions: if b2i(t) in unpacker_coercions:
desc = desc.AECoerceDesc(unpacker_coercions[t]) desc = desc.AECoerceDesc(unpacker_coercions[b2i(t)])
t = desc.type # This is a guess by Jack.... t = desc.type # This is a guess by Jack....
if t == typeAEList: if t == typeAEList:
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, b'****')
l.append(unpack(item, formodulename)) 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, b'****')
d[keyword] = unpack(item, formodulename) d[b2i(keyword)] = unpack(item, formodulename)
return d return d
if t == typeAEText: if t == typeAEText:
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc(b'reco')
return mkaetext(unpack(record, formodulename)) return mkaetext(unpack(record, formodulename))
if t == typeAlias: if t == typeAlias:
return Carbon.File.Alias(rawdata=desc.data) return Carbon.File.Alias(rawdata=desc.data)
@ -170,7 +178,7 @@ def unpack(desc, formodulename=""):
if t == typeFSRef: if t == typeFSRef:
return Carbon.File.FSRef(rawdata=desc.data) return Carbon.File.FSRef(rawdata=desc.data)
if t == typeInsertionLoc: if t == typeInsertionLoc:
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc(b'reco')
return mkinsertionloc(unpack(record, formodulename)) return mkinsertionloc(unpack(record, formodulename))
# typeInteger equal to typeLongInteger # typeInteger equal to typeLongInteger
if t == typeIntlText: if t == typeIntlText:
@ -194,7 +202,7 @@ def unpack(desc, formodulename=""):
v = 0x100000000 + v v = 0x100000000 + v
return v return v
if t == typeObjectSpecifier: if t == typeObjectSpecifier:
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc(b'reco')
# If we have been told the name of the module we are unpacking aedescs for, # 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. # we can attempt to create the right type of python object from that module.
if formodulename: if formodulename:
@ -234,14 +242,14 @@ def unpack(desc, formodulename=""):
# #
# The following are special # The following are special
# #
if t == 'rang': if t == b'rang':
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc(b'reco')
return mkrange(unpack(record, formodulename)) return mkrange(unpack(record, formodulename))
if t == 'cmpd': if t == b'cmpd':
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc(b'reco')
return mkcomparison(unpack(record, formodulename)) return mkcomparison(unpack(record, formodulename))
if t == 'logi': if t == b'logi':
record = desc.AECoerceDesc('reco') record = desc.AECoerceDesc(b'reco')
return mklogical(unpack(record, formodulename)) return mklogical(unpack(record, formodulename))
return mkunknown(desc.type, desc.data) return mkunknown(desc.type, desc.data)
@ -297,39 +305,44 @@ def mkkeyword(keyword):
return aetypes.Keyword(keyword) return aetypes.Keyword(keyword)
def mkrange(dict): def mkrange(dict):
return aetypes.Range(dict['star'], dict['stop']) return aetypes.Range(dict[b2i(b'star')], dict[b2i(b'stop')])
def mkcomparison(dict): def mkcomparison(dict):
return aetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2']) return aetypes.Comparison(dict[b2i(b'obj1')],
dict[b2i(b'relo')].enum,
dict[b2i(b'obj2')])
def mklogical(dict): def mklogical(dict):
return aetypes.Logical(dict['logc'], dict['term']) return aetypes.Logical(dict[b2i(b'logc')], dict[b2i(b'term')])
def mkstyledtext(dict): def mkstyledtext(dict):
return aetypes.StyledText(dict['ksty'], dict['ktxt']) return aetypes.StyledText(dict[b2i(b'ksty')], dict[b2i(b'ktxt')])
def mkaetext(dict): def mkaetext(dict):
return aetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText]) return aetypes.AEText(dict[b2i(keyAEScriptTag)],
dict[b2i(keyAEStyles)],
dict[b2i(keyAEText)])
def mkinsertionloc(dict): def mkinsertionloc(dict):
return aetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition]) return aetypes.InsertionLoc(dict[b2i(keyAEObject)],
dict[b2i(keyAEPosition)])
def mkobject(dict): def mkobject(dict):
want = dict['want'].type want = dict[b2i(b'want')].type
form = dict['form'].enum form = dict[b2i(b'form')].enum
seld = dict['seld'] seld = dict[b2i(b'seld')]
fr = dict['from'] fr = dict[b2i(b'from')]
if form in ('name', 'indx', 'rang', 'test'): if form in (b'name', b'indx', b'rang', b'test'):
if want == 'text': return aetypes.Text(seld, fr) if want == b'text': return aetypes.Text(seld, fr)
if want == 'cha ': return aetypes.Character(seld, fr) if want == b'cha ': return aetypes.Character(seld, fr)
if want == 'cwor': return aetypes.Word(seld, fr) if want == b'cwor': return aetypes.Word(seld, fr)
if want == 'clin': return aetypes.Line(seld, fr) if want == b'clin': return aetypes.Line(seld, fr)
if want == 'cpar': return aetypes.Paragraph(seld, fr) if want == b'cpar': return aetypes.Paragraph(seld, fr)
if want == 'cwin': return aetypes.Window(seld, fr) if want == b'cwin': return aetypes.Window(seld, fr)
if want == 'docu': return aetypes.Document(seld, fr) if want == b'docu': return aetypes.Document(seld, fr)
if want == 'file': return aetypes.File(seld, fr) if want == b'file': return aetypes.File(seld, fr)
if want == 'cins': return aetypes.InsertionPoint(seld, fr) if want == b'cins': return aetypes.InsertionPoint(seld, fr)
if want == 'prop' and form == 'prop' and aetypes.IsType(seld): if want == b'prop' and form == b'prop' and aetypes.IsType(seld):
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)
@ -338,14 +351,15 @@ def mkobject(dict):
# to __class__ is safe. Moreover, shouldn't there be a better # to __class__ is safe. Moreover, shouldn't there be a better
# initializer for the classes in the suites? # initializer for the classes in the suites?
def mkobjectfrommodule(dict, modulename): def mkobjectfrommodule(dict, modulename):
if isinstance(dict['want'], type) and issubclass(dict['want'], ObjectSpecifier): if (isinstance(dict[b2i(b'want')], type) and
issubclass(dict[b2i(b'want')], ObjectSpecifier)):
# The type has already been converted to Python. Convert back:-( # The type has already been converted to Python. Convert back:-(
classtype = dict['want'] classtype = dict[b2i(b'want')]
dict['want'] = aetypes.mktype(classtype.want) dict[b2i(b'want')] = aetypes.mktype(classtype.want)
want = dict['want'].type want = dict[b2i(b'want')].type
module = __import__(modulename) module = __import__(modulename)
codenamemapper = module._classdeclarations codenamemapper = module._classdeclarations
classtype = codenamemapper.get(want, None) classtype = codenamemapper.get(b2i(want), None)
newobj = mkobject(dict) newobj = mkobject(dict)
if classtype: if classtype:
assert issubclass(classtype, ObjectSpecifier) assert issubclass(classtype, ObjectSpecifier)
@ -356,7 +370,7 @@ def mktype(typecode, modulename=None):
if modulename: if modulename:
module = __import__(modulename) module = __import__(modulename)
codenamemapper = module._classdeclarations codenamemapper = module._classdeclarations
classtype = codenamemapper.get(typecode, None) classtype = codenamemapper.get(b2i(typecode), None)
if classtype: if classtype:
return classtype return classtype
return aetypes.mktype(typecode) return aetypes.mktype(typecode)

View File

@ -16,6 +16,14 @@ def nice(s):
if isinstance(s, str): return repr(s) if isinstance(s, str): return repr(s)
else: return str(s) else: return str(s)
def _four_char_code(four_chars):
"""Convert a str or bytes object into a 4-byte array.
four_chars must contain only ASCII characters.
"""
return bytes("%-4.4s" % str(four_chars))
class Unknown: class Unknown:
"""An uninterpreted AE object""" """An uninterpreted AE object"""
@ -33,13 +41,13 @@ class Enum:
"""An AE enumeration value""" """An AE enumeration value"""
def __init__(self, enum): def __init__(self, enum):
self.enum = "%-4.4s" % str(enum) self.enum = _four_char_code(enum)
def __repr__(self): def __repr__(self):
return "Enum(%r)" % (self.enum,) return "Enum(%r)" % (self.enum,)
def __str__(self): def __str__(self):
return self.enum.strip() return self.enum.strip(b' ')
def __aepack__(self): def __aepack__(self):
return pack(self.enum, typeEnumeration) return pack(self.enum, typeEnumeration)
@ -100,7 +108,7 @@ class Type:
"""An AE 4-char typename object""" """An AE 4-char typename object"""
def __init__(self, type): def __init__(self, type):
self.type = "%-4.4s" % str(type) self.type = _four_char_code(type)
def __repr__(self): def __repr__(self):
return "Type(%r)" % (self.type,) return "Type(%r)" % (self.type,)
@ -123,7 +131,7 @@ class Keyword:
"""An AE 4-char keyword object""" """An AE 4-char keyword object"""
def __init__(self, keyword): def __init__(self, keyword):
self.keyword = "%-4.4s" % str(keyword) self.keyword = _four_char_code(keyword)
def __repr__(self): def __repr__(self):
return "Keyword(%r)" % self.keyword return "Keyword(%r)" % self.keyword
@ -161,7 +169,7 @@ class Comparison:
def __init__(self, obj1, relo, obj2): def __init__(self, obj1, relo, obj2):
self.obj1 = obj1 self.obj1 = obj1
self.relo = "%-4.4s" % str(relo) self.relo = _four_char_code(relo)
self.obj2 = obj2 self.obj2 = obj2
def __repr__(self): def __repr__(self):
@ -190,7 +198,7 @@ class Ordinal:
def __init__(self, abso): def __init__(self, abso):
# self.obj1 = obj1 # self.obj1 = obj1
self.abso = "%-4.4s" % str(abso) self.abso = _four_char_code(abso)
def __repr__(self): def __repr__(self):
return "Ordinal(%r)" % (self.abso,) return "Ordinal(%r)" % (self.abso,)
@ -214,7 +222,7 @@ class Logical:
"""An AE logical expression object""" """An AE logical expression object"""
def __init__(self, logc, term): def __init__(self, logc, term):
self.logc = "%-4.4s" % str(logc) self.logc = _four_char_code(logc)
self.term = term self.term = term
def __repr__(self): def __repr__(self):
@ -554,12 +562,12 @@ template = """
class %s(ComponentItem): want = '%s' class %s(ComponentItem): want = '%s'
""" """
exec(template % ("Text", 'text')) exec(template % ("Text", b'text'))
exec(template % ("Character", 'cha ')) exec(template % ("Character", b'cha '))
exec(template % ("Word", 'cwor')) exec(template % ("Word", b'cwor'))
exec(template % ("Line", 'clin')) exec(template % ("Line", b'clin'))
exec(template % ("paragraph", 'cpar')) exec(template % ("paragraph", b'cpar'))
exec(template % ("Window", 'cwin')) exec(template % ("Window", b'cwin'))
exec(template % ("Document", 'docu')) exec(template % ("Document", b'docu'))
exec(template % ("File", 'file')) exec(template % ("File", b'file'))
exec(template % ("InsertionPoint", 'cins')) exec(template % ("InsertionPoint", b'cins'))

View File

@ -8,18 +8,18 @@ from test import test_support
class TestAepack(unittest.TestCase): class TestAepack(unittest.TestCase):
OBJECTS = [ OBJECTS = [
aetypes.Enum('enum'), aetypes.Enum(b'enum'),
aetypes.Type('type'), aetypes.Type(b'type'),
aetypes.Keyword('kwrd'), aetypes.Keyword(b'kwrd'),
aetypes.Range(1, 10), aetypes.Range(1, 10),
aetypes.Comparison(1, '< ', 10), aetypes.Comparison(1, b'< ', 10),
aetypes.Logical('not ', 1), aetypes.Logical(b'not ', 1),
aetypes.IntlText(0, 0, 'international text'), aetypes.IntlText(0, 0, b'international text'),
aetypes.IntlWritingCode(0,0), aetypes.IntlWritingCode(0,0),
aetypes.QDPoint(50,100), aetypes.QDPoint(50,100),
aetypes.QDRectangle(50,100,150,200), aetypes.QDRectangle(50,100,150,200),
aetypes.RGBColor(0x7000, 0x6000, 0x5000), aetypes.RGBColor(0x7000, 0x6000, 0x5000),
aetypes.Unknown('xxxx', 'unknown type data'), aetypes.Unknown(b'xxxx', b'unknown type data'),
aetypes.Character(1), aetypes.Character(1),
aetypes.Character(2, aetypes.Line(2)), aetypes.Character(2, aetypes.Line(2)),
] ]

View File

@ -12,8 +12,8 @@ import applesingle
AS_MAGIC=0x00051600 AS_MAGIC=0x00051600
AS_VERSION=0x00020000 AS_VERSION=0x00020000
dataforkdata = 'hello\r\0world\n' dataforkdata = b'hello\r\0world\n'
resourceforkdata = 'goodbye\ncruel\0world\r' resourceforkdata = b'goodbye\ncruel\0world\r'
applesingledata = struct.pack(">ll16sh", AS_MAGIC, AS_VERSION, "foo", 2) + \ applesingledata = struct.pack(">ll16sh", AS_MAGIC, AS_VERSION, "foo", 2) + \
struct.pack(">llllll", 1, 50, len(dataforkdata), struct.pack(">llllll", 1, 50, len(dataforkdata),
@ -25,7 +25,7 @@ TESTFN2 = test_support.TESTFN + '2'
class TestApplesingle(unittest.TestCase): class TestApplesingle(unittest.TestCase):
def setUp(self): def setUp(self):
fp = open(test_support.TESTFN, 'w') fp = open(test_support.TESTFN, 'wb')
fp.write(applesingledata) fp.write(applesingledata)
fp.close() fp.close()

View File

@ -835,9 +835,9 @@ static PyObject *AEDesc_get_data(AEDescObject *self, void *closure)
OSErr err; OSErr err;
size = AEGetDescDataSize(&self->ob_itself); size = AEGetDescDataSize(&self->ob_itself);
if ( (res = PyString_FromStringAndSize(NULL, size)) == NULL ) if ( (res = PyBytes_FromStringAndSize(NULL, size)) == NULL )
return NULL; return NULL;
if ( (ptr = PyString_AsString(res)) == NULL ) if ( (ptr = PyBytes_AsString(res)) == NULL )
return NULL; return NULL;
if ( (err=AEGetDescData(&self->ob_itself, ptr, size)) < 0 ) if ( (err=AEGetDescData(&self->ob_itself, ptr, size)) < 0 )
return PyMac_Error(err); return PyMac_Error(err);

View File

@ -194,7 +194,7 @@ PyObject *
PyMac_BuildOSType(OSType t) PyMac_BuildOSType(OSType t)
{ {
uint32_t tmp = htonl((uint32_t)t); uint32_t tmp = htonl((uint32_t)t);
return PyString_FromStringAndSize((char *)&tmp, 4); return PyBytes_FromStringAndSize((char *)&tmp, 4);
} }
/* Convert an NumVersion value to a 4-element tuple */ /* Convert an NumVersion value to a 4-element tuple */
@ -215,7 +215,7 @@ PyMac_GetStr255(PyObject *v, Str255 pbuf)
if (PyUnicode_Check(v)) { if (PyUnicode_Check(v)) {
v = _PyUnicode_AsDefaultEncodedString(v, NULL); v = _PyUnicode_AsDefaultEncodedString(v, NULL);
if (v == NULL) if (v == NULL)
return NULL; return 0;
} }
if (PyString_Check(v)) { if (PyString_Check(v)) {
ptr = PyString_AS_STRING(v); ptr = PyString_AS_STRING(v);