Conversion.py :  » Development » PyObjC » trunk » pyobjc » pyobjc-framework-Cocoa » Lib » PyObjCTools » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » PyObjC 
PyObjC » trunk » pyobjc » pyobjc framework Cocoa » Lib » PyObjCTools » Conversion.py
"""
Conversion.py -- Tools for converting between Python and Objective-C objects.

Conversion offers API to convert between Python and Objective-C instances of 
various classes.   Currently, the focus is on Python and Objective-C 
collections.
"""

__all__ = [
    'pythonCollectionFromPropertyList', 'propertyListFromPythonCollection',
    'serializePropertyList', 'deserializePropertyList',
    'toPythonDecimal', 'fromPythonDecimal',
]

from Foundation import *
import datetime
import time
try:
    import decimal
except ImportError:
    decimal = None

PYTHON_TYPES = (
    basestring, bool, int, float, long, list, tuple, dict,
    datetime.date, datetime.datetime, bool, buffer, type(None),
)

DECIMAL_LOCALE = NSDictionary.dictionaryWithObject_forKey_(
    u'.', 'NSDecimalSeparator')

def toPythonDecimal(aNSDecimalNumber):
    """
    Convert a NSDecimalNumber to a Python decimal.Decimal
    """
    return decimal.Decimal(
        aNSDecimalNumber.descriptionWithLocale_(DECIMAL_LOCALE))

def fromPythonDecimal(aPythonDecimal):
    """
    Convert a Python decimal.Decimal to a NSDecimalNumber
    """
    return NSDecimalNumber.decimalNumberWithString_locale_(
        unicode(aPythonDecimal), DECIMAL_LOCALE)

FORMATS = dict(
    xml=NSPropertyListXMLFormat_v1_0,
    binary=NSPropertyListBinaryFormat_v1_0,
    ascii=NSPropertyListOpenStepFormat,
)

def serializePropertyList(aPropertyList, format='xml'):
    """
    Serialize a property list to an NSData object.  Format is one of the
    following strings:
    
    xml (default):
        NSPropertyListXMLFormat_v1_0, the XML representation

    binary:
        NSPropertyListBinaryFormat_v1_0, the efficient binary representation

    ascii:
        NSPropertyListOpenStepFormat, the old-style ASCII property list

    It is expected that this property list is comprised of Objective-C
    objects.  In most cases Python data structures will work, but
    decimal.Decimal and datetime.datetime objects are not transparently
    bridged so it will fail in that case.  If you expect to have these
    objects in your property list, then use propertyListFromPythonCollection
    before serializing it.
    """
    try:
        formatOption = FORMATS[format]
    except KeyError:
        raise TypeError("Invalid format: %s" % (format,))
    data, err = NSPropertyListSerialization.dataFromPropertyList_format_errorDescription_(aPropertyList, formatOption)
    if err is not None:
        # braindead API!
        errStr = err.encode('utf-8')
        err.release()
        raise TypeError(errStr)
    return data

def deserializePropertyList(propertyListData):
    """
    Deserialize a property list from a NSData, str, unicode or buffer

    Returns an Objective-C property list.
    """
    if isinstance(propertyListData, str):
        propertyListData = buffer(propertyListData)
    elif isinstance(propertyListData, unicode):
        propertyListData = buffer(propertyListData.encode('utf-8'))
    plist, fmt, err = NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_(propertyListData, NSPropertyListMutableContainers)
    if err is not None:
        # braindead API!
        errStr = err.encode('utf-8')
        err.release()
        raise TypeError(errStr)
    return plist

def propertyListFromPythonCollection(aPyCollection, conversionHelper=None):
    """
    Convert a Python collection (dict, list, tuple, string) into an
    Objective-C collection.

    If conversionHelper is defined, it must be a callable.  It will be called
    for any object encountered for which propertyListFromPythonCollection()
    cannot automatically convert the object.   The supplied helper function
    should convert the object and return the converted form.  If the conversion
    helper cannot convert the type, it should raise an exception or return
    None.
    """
    if isinstance(aPyCollection, dict):
        collection = NSMutableDictionary.dictionary()
        for aKey in aPyCollection:
            if not isinstance(aKey, basestring):
                raise TypeError("Property list keys must be strings")
            convertedValue = propertyListFromPythonCollection(
                aPyCollection[aKey], conversionHelper=conversionHelper)
            collection[aKey] = convertedValue
        return collection
    elif isinstance(aPyCollection, (list, tuple)):
        collection = NSMutableArray.array()
        for aValue in aPyCollection:
            convertedValue = propertyListFromPythonCollection(aValue,
                conversionHelper=conversionHelper)
            collection.append(aValue)
        return collection
    elif isinstance(aPyCollection, (datetime.datetime, datetime.date)):
        return NSDate.dateWithTimeIntervalSince1970_(
            time.mktime(aPyCollection.timetuple()))
    elif decimal is not None and isinstance(aPyCollection, decimal.Decimal):
        return fromPythonDecimal(aPyCollection)
    elif isinstance(aPyCollection, PYTHON_TYPES):
        # bridge will convert
        return aPyCollection
    elif conversionHelper is not None:
        return conversionHelper(aPyCollection)
    raise TypeError("Type '%s' encountered in Python collection; don't know how to convert." % type(aPyCollection))


def pythonCollectionFromPropertyList(aCollection, conversionHelper=None):
    """
    Converts a Foundation based property list into a Python
    collection (all members will be instances or subclasses of standard Python
    types)

    Like propertyListFromPythonCollection(), conversionHelper is an optional
    callable that will be invoked any time an encountered object cannot be
    converted.
    """
    if isinstance(aCollection, NSDictionary):
        pyCollection = {}
        for k in aCollection:
            if not isinstance(k, basestring):
                raise TypeError("Property list keys must be strings")
            convertedValue = pythonCollectionFromPropertyList(
                aCollection[k], conversionHelper)
            pyCollection[k] = convertedValue
        return pyCollection
    elif isinstance(aCollection, NSArray):
        return [
            pythonCollectionFromPropertyList(item, conversionHelper)
            for item in aCollection
        ]
    elif isinstance(aCollection, NSData):
        return buffer(aCollection)
    elif isinstance(aCollection, NSDate):
        return datetime.datetime.fromtimestamp(
            aCollection.timeIntervalSince1970())
    elif isinstance(aCollection, NSDecimalNumber) and decimal is not None:
        return toPythonDecimal(aCollection)
    elif aCollection is NSNull.null():
        return None
    elif isinstance(aCollection, PYTHON_TYPES):
        return aCollection
    elif conversionHelper:
        return conversionHelper(aCollection)
    raise TypeError("Type '%s' encountered in ObjC collection;  don't know how to convert." % type(aCollection))
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.