Commits

Ronald Oussoren committed 02dfa37

Deprecate addConvenienceForSelector to enable work on issue #3

objc.addConvenienceForSelector makes it harder to implement the optimization
mentioned in issue #3, I'm therefore deprecating this function.

Also started work on removing the current use of that functionality from
pyobjc-core, although much more work it needed.

Comments (0)

Files changed (3)

pyobjc-core/Lib/objc/_convenience.py

 from objc._objc import _setClassExtender, selector, lookUpClass, currentBundle, repythonify, splitSignature, _block_call
 from objc._objc import registerMetaDataForSelector
 import sys
+import warnings
 
 __all__ = ( 'addConvenienceForSelector', 'addConvenienceForClass' )
 
 
-CONVENIENCE_METHODS = {}
+_CONVENIENCE_METHODS = {}
 CLASS_METHODS = {}
 
 if sys.version_info[0] == 3:
     # XXX: Temporary backward compatibily
     xrange = range
 
+
 def addConvenienceForSelector(selector, methods):
     """
     Add the list with methods to every class that has a selector with the
     given name.
     """
-    CONVENIENCE_METHODS[selector] = methods
+    warning.warn("addConvenienceForSelector is on the way out", DeprecationWarning)
+    _CONVENIENCE_METHODS[selector] = methods
 
 def addConvenienceForClass(classname, methods):
     """
     Add additional methods to the type-dict of subclass 'name' of
     'super_class'.
 
-    CONVENIENCE_METHODS is a global variable containing a mapping from
+    _CONVENIENCE_METHODS is a global variable containing a mapping from
     an Objective-C selector to a Python method name and implementation.
 
     CLASS_METHODS is a global variable containing a mapping from
 
         sel = sel.selector
 
-        if sel in CONVENIENCE_METHODS:
-            v = CONVENIENCE_METHODS[sel]
+        if sel in _CONVENIENCE_METHODS:
+            v = _CONVENIENCE_METHODS[sel]
             for nm, value in v:
                 if nm in type_dict and isinstance(type_dict[nm], selector):
 
         res = dflt
     return res
 
-CONVENIENCE_METHODS[b'objectForKey:'] = (
+_CONVENIENCE_METHODS[b'objectForKey:'] = (
     ('__getitem__', __getitem__objectForKey_),
     ('get', get_objectForKey_),
     ('__contains__', has_key_objectForKey_),
 )
 if sys.version_info[0] == 2:
-    CONVENIENCE_METHODS[b'objectForKey:'] += (
+    _CONVENIENCE_METHODS[b'objectForKey:'] += (
         ('has_key', has_key_objectForKey_),
     )
 
 def __delitem__removeObjectForKey_(self, key):
     self.removeObjectForKey_(container_wrap(key))
 
-CONVENIENCE_METHODS[b'removeObjectForKey:'] = (
+_CONVENIENCE_METHODS[b'removeObjectForKey:'] = (
     ('__delitem__', __delitem__removeObjectForKey_),
 )
 
         self.removeObjectForKey_(k)
         return result
 
-CONVENIENCE_METHODS[b'setObject:forKey:'] = (
+_CONVENIENCE_METHODS[b'setObject:forKey:'] = (
     ('__setitem__', __setitem__setObject_forKey_),
     ('update', update_setObject_forKey_),
     ('setdefault', setdefault_setObject_forKey_),
 )
 
 
-CONVENIENCE_METHODS[b'count'] = (
+_CONVENIENCE_METHODS[b'count'] = (
     ('__len__', lambda self: self.count()),
 )
 
 def containsObject_has_key(self, elem):
     return bool(self.containsObject_(container_wrap(elem)))
 
-CONVENIENCE_METHODS[b'containsObject:'] = (
+_CONVENIENCE_METHODS[b'containsObject:'] = (
     ('__contains__', containsObject_has_key),
 )
 
 
 
-def objc_hash(self, _max=sys.maxsize, _const=((sys.maxsize + 1) * 2)):
+def nsobject_hash(self, _max=sys.maxsize, _const=((sys.maxsize + 1) * 2)):
     rval = self.hash()
     if rval > _max:
         rval -= _const
         if rval == -1:
             rval = -2
     return int(rval)
-CONVENIENCE_METHODS[b'hash'] = (
-    ('__hash__', objc_hash),
+
+def nsobject__eq__(self, other):
+    return bool(self.isEqualTo_(other))
+
+def nsobject__ne__(self, other):
+    return bool(self.isNotEqualTo_(other))
+
+def nsobject__gt__(self, other):
+    return bool(self.isGreaterThan_(other))
+
+def nsobject__ge__(self, other):
+    return bool(self.isGreaterThanOrEqualTo_(other))
+
+def nsobject__lt__(self, other):
+    return bool(self.isLessThan_(other))
+
+def nsobject__le__(self, other):
+    return bool(self.isLessThanOrEqualTo_(other))
+
+CLASS_METHODS["NSObject"] = (
+    ('__hash__', nsobject_hash),
+    ('__eq__', nsobject__eq__),
+    ('__ne__', nsobject__ne__),
+    ('__gt__', nsobject__gt__),
+    ('__ge__', nsobject__ge__),
+    ('__lt__', nsobject__lt__),
+    ('__le__', nsobject__le__),
 )
 
 if sys.version_info[0] == 2:
-    CONVENIENCE_METHODS[b'compare:'] = (
-        ('__cmp__', lambda self, other: bool(self.compare_(other))),
+    def nsobject__cmp__(self, other):
+        try:
+            func = self.compare_
+
+        except AttributeError:
+            if self < other:
+                return -1
+            elif self > other:
+                return 1
+            else:
+                return 0
+
+        else:
+            return func(other)
+
+    CLASS_OBJECTS["NSObject"] += (
+        ("__cmp__", nsobject__cmp__),
     )
 
-CONVENIENCE_METHODS[b'isEqualTo:'] = (
-    ('__eq__', lambda self, other: bool(self.isEqualTo_(other))),
-)
 
-CONVENIENCE_METHODS[b'isEqual:'] = (
-    ('__eq__', lambda self, other: bool(self.isEqual_(other))),
-)
 
-CONVENIENCE_METHODS[b'isGreaterThan:'] = (
-    ('__gt__', lambda self, other: bool(self.isGreaterThan_(other))),
-)
 
-CONVENIENCE_METHODS[b'isGreaterThanOrEqualTo:'] = (
-    ('__ge__', lambda self, other: bool(self.isGreaterThanOrEqualTo_(other))),
-)
-
-CONVENIENCE_METHODS[b'isLessThan:'] = (
-    ('__lt__', lambda self, other: bool(self.isLessThan_(other))),
-)
-
-CONVENIENCE_METHODS[b'isLessThanOrEqualTo:'] = (
-    ('__le__', lambda self, other: bool(self.isLessThanOrEqualTo_(other))),
-)
-
-CONVENIENCE_METHODS[b'isNotEqualTo:'] = (
-    ('__ne__', lambda self, other: bool(self.isNotEqualTo_(other))),
-)
-
-CONVENIENCE_METHODS[b'length'] = (
+_CONVENIENCE_METHODS[b'length'] = (
     ('__len__', lambda self: self.length()),
 )
 
-CONVENIENCE_METHODS[b'addObject:'] = (
+_CONVENIENCE_METHODS[b'addObject:'] = (
     ('append', lambda self, item: self.addObject_(container_wrap(item))),
 )
 
         begin += 1
         end -= 1
 
-CONVENIENCE_METHODS[b'exchangeObjectAtIndex:withObjectAtIndex:'] = (
+_CONVENIENCE_METHODS[b'exchangeObjectAtIndex:withObjectAtIndex:'] = (
     ('reverse', reverse_exchangeObjectAtIndex_withObjectAtIndex_),
 )
 
 def extend_addObjectsFromArray_(self, anArray):
     self.addObjectsFromArray_(ensureArray(anArray))
 
-CONVENIENCE_METHODS[b'addObjectsFromArray:'] = (
+_CONVENIENCE_METHODS[b'addObjectsFromArray:'] = (
     ('extend', extend_addObjectsFromArray_),
 )
 
                 raise ValueError("%s.index(x): x not in list" % (type(self).__name__,))
     return res
 
-CONVENIENCE_METHODS[b'indexOfObject:inRange:'] = (
+_CONVENIENCE_METHODS[b'indexOfObject:inRange:'] = (
     ('index', index_indexOfObject_inRange_),
 )
 
             raise IndexError("list index out of range")
     self.insertObject_atIndex_(container_wrap(item), idx)
 
-CONVENIENCE_METHODS[b'insertObject:atIndex:'] = (
+_CONVENIENCE_METHODS[b'insertObject:atIndex:'] = (
     ( 'insert', insert_insertObject_atIndex_),
 )
 
     i = max(i, 0); j = max(j, 0)
     return __getitem__objectAtIndex_(self, slice(i, j))
 
-CONVENIENCE_METHODS[b'objectAtIndex:'] = (
+_CONVENIENCE_METHODS[b'objectAtIndex:'] = (
     ('__getitem__', __getitem__objectAtIndex_),
     ('__getslice__', __getslice__objectAtIndex_),
 )
     idx = self.index(obj)
     self.removeObjectAtIndex_(idx)
 
-CONVENIENCE_METHODS[b'removeObjectAtIndex:'] = (
+_CONVENIENCE_METHODS[b'removeObjectAtIndex:'] = (
     ('remove', remove_removeObjectAtIndex_),
     ('pop', pop_removeObjectAtIndex_),
     ('__delitem__', __delitem__removeObjectAtIndex_),
     j = max(j, 0)
     __setitem__replaceObjectAtIndex_withObject_(self, slice(i, j), seq)
 
-CONVENIENCE_METHODS[b'replaceObjectAtIndex:withObject:'] = (
+_CONVENIENCE_METHODS[b'replaceObjectAtIndex:withObject:'] = (
     ('__setitem__', __setitem__replaceObjectAtIndex_withObject_),
     ('__setslice__', __setslice__replaceObjectAtIndex_withObject_),
 )
         meth = self.objectEnumerator
     return iter(meth())
 
-CONVENIENCE_METHODS[b'keyEnumerator'] = (
+_CONVENIENCE_METHODS[b'keyEnumerator'] = (
     ('__iter__', __iter__objectEnumerator_keyEnumerator),
 )
 if sys.version_info[0] == 2:
-    CONVENIENCE_METHODS[b'keyEnumerator'] += (
+    _CONVENIENCE_METHODS[b'keyEnumerator'] += (
         ('iterkeys', lambda self: iter(self.keyEnumerator())),
         ('iteritems', lambda self: itemsGenerator(self)),
 )
 
-CONVENIENCE_METHODS[b'objectEnumerator'] = (
+_CONVENIENCE_METHODS[b'objectEnumerator'] = (
     ('__iter__', __iter__objectEnumerator_keyEnumerator),
 )
 
 if sys.version_info[0] == 2:
-    CONVENIENCE_METHODS[b'objectEnumerator'] += (
+    _CONVENIENCE_METHODS[b'objectEnumerator'] += (
         ('itervalues', lambda self: iter(self.objectEnumerator())),
     )
 
-CONVENIENCE_METHODS[b'reverseObjectEnumerator'] = (
+_CONVENIENCE_METHODS[b'reverseObjectEnumerator'] = (
     ('__reversed__', lambda self: iter(self.reverseObjectEnumerator())),
 )
 
-CONVENIENCE_METHODS[b'removeAllObjects'] = (
+_CONVENIENCE_METHODS[b'removeAllObjects'] = (
     ('clear', lambda self: self.removeAllObjects()),
 )
 
-CONVENIENCE_METHODS[b'dictionaryWithDictionary:'] = (
+_CONVENIENCE_METHODS[b'dictionaryWithDictionary:'] = (
     ('copy', lambda self: type(self).dictionaryWithDictionary_(self)),
 )
 
-CONVENIENCE_METHODS[b'nextObject'] = (
+_CONVENIENCE_METHODS[b'nextObject'] = (
     ('__iter__', enumeratorGenerator),
 )
 
         ))
 
 
-CONVENIENCE_METHODS[b'sortUsingFunction:context:'] = (
+_CONVENIENCE_METHODS[b'sortUsingFunction:context:'] = (
     ('sort', sort),
 )
 
-CONVENIENCE_METHODS[b'hasPrefix:'] = (
+_CONVENIENCE_METHODS[b'hasPrefix:'] = (
     ('startswith', lambda self, pfx: self.hasPrefix_(pfx)),
 )
 
-CONVENIENCE_METHODS[b'hasSuffix:'] = (
+_CONVENIENCE_METHODS[b'hasSuffix:'] = (
     ('endswith', lambda self, pfx: self.hasSuffix_(pfx)),
 )
 
     if hasattr(self, 'mutableCopy'):
         return self.mutableCopyWithZone_(None)
     return self.copyWithZone_(None)
-CONVENIENCE_METHODS[b'copyWithZone:'] = (
+_CONVENIENCE_METHODS[b'copyWithZone:'] = (
     ('__copy__', __copy__),
 )
 
 #   result = NSKeyedUnarchiver.unarchiveObjectWithData_(buf)
 #   return result
 #
-#CONVENIENCE_METHODS['encodeWithCoder:'] = (
+#_CONVENIENCE_METHODS['encodeWithCoder:'] = (
 #   ('__deepcopy__', coder_deepcopy ),
 #)
 

pyobjc-core/NEWS.txt

 Version 2.4  (or 3.0)
 ---------------------
 
+- ``objc.addConvenienceForSelector`` is deprecated, primarily to make 
+  it possible to restructure the pyobjc internals.
+
 - Workaround for bug in pip that resulted in pyobjc-core not being pip
   installable.  Patch by Marc Abramowitz.
 

pyobjc-framework-AddressBook/Lib/AddressBook/__init__.py

 
 from AddressBook import _metadata
 
+objc.addConvenienceForClass("ABAbstractAccountConfiguration", (
+    ('__setitem__', ABAbstractAccountConfiguration__setitem__),
+    ('__getitem__', ABAbstractAccountConfiguration__getitem__),
+))
+
 sys.modules['AddressBook'] = mod = objc.ObjCLazyModule(
     "AddressBook",
     "com.apple.AddressBook.framework",