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