1import _objc
2
3__all__ = []
4
5
6class OC_PythonFloat(float):
7    __slots__=('__pyobjc_object__',)
8
9
10    def __new__(cls, obj, value):
11        self = float.__new__(cls, value)
12        self.__pyobjc_object__ = obj
13        return self
14
15    __class__ = property(lambda self: self.__pyobjc_object__.__class__)
16
17    def __getattr__(self, attr):
18        return getattr(self.__pyobjc_object__, attr)
19
20    def __reduce__(self):
21        return (float, (float(self),))
22
23class OC_PythonLong(long):
24
25    def __new__(cls, obj, value):
26        self = long.__new__(cls, value)
27        self.__pyobjc_object__ = obj
28        return self
29
30    __class__ = property(lambda self: self.__pyobjc_object__.__class__)
31
32    def __getattr__(self, attr):
33        return getattr(self.__pyobjc_object__, attr)
34
35    # The long type doesn't support __slots__ on subclasses, fake
36    # one part of the effect of __slots__: don't allow setting of attributes.
37    def __setattr__(self, attr, value):
38        if attr != '__pyobjc_object__':
39            raise AttributeError, "'%s' object has no attribute '%s')"%(self.__class__.__name__, attr)
40        self.__dict__['__pyobjc_object__'] = value
41
42    def __reduce__(self):
43        return (long, (long(self),))
44
45class OC_PythonInt(int):
46    __slots__=('__pyobjc_object__',)
47
48    def __new__(cls, obj, value):
49        self = int.__new__(cls, value)
50        self.__pyobjc_object__ = obj
51        return self
52
53    __class__ = property(lambda self: self.__pyobjc_object__.__class__)
54
55    def __getattr__(self, attr):
56        return getattr(self.__pyobjc_object__, attr)
57
58    def __reduce__(self):
59        return (int, (int(self),))
60
61NSNumber = _objc.lookUpClass('NSNumber')
62NSDecimalNumber = _objc.lookUpClass('NSDecimalNumber')
63Foundation = None
64
65def numberWrapper(obj):
66    if isinstance(obj, NSDecimalNumber):
67        return obj
68        # ensure that NSDecimal is around
69        global Foundation
70        if Foundation is None:
71            import Foundation
72        # return NSDecimal
73        return Foundation.NSDecimal(obj)
74    try:
75        tp = obj.objCType()
76    except AttributeError:
77        import warnings
78        warnings.warn(RuntimeWarning, "NSNumber instance doesn't implement objCType? %r" % (obj,))
79        return obj
80    if tp in 'qQLfd':
81        if tp == 'q':
82            return OC_PythonLong(obj, obj.longLongValue())
83        elif tp in 'QL':
84            return OC_PythonLong(obj, obj.unsignedLongLongValue())
85        elif tp == 'd':
86            return OC_PythonFloat(obj, obj.doubleValue())
87        else:
88            return OC_PythonFloat(obj, obj.floatValue())
89    else:
90        return OC_PythonInt(obj, obj.longValue())
91
92_objc._setNSNumberWrapper(numberWrapper)
93